我想绘制并填充一条由 2 条弧和 2 条线组成的特定颜色的路径。我需要使用 JavaFX 中的 Canvas,因为我需要绘制更多内容。问题是,我创建的路径甚至没有绘制或填充。我想要的是这个
但是我的代码产生了这个
您可能会注意到,这条弧线在左侧和右侧比在中间更细。不幸的是,仅使用具有一定笔划宽度的简单弧线对我来说不是一个选择。
这是我的代码,其中注释部分生成第二张图像。我已经尝试使用绘制路径设施并填充它,但它不起作用
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.paint.Color;
import javafx.scene.shape.ArcType;
import javafx.stage.Stage;
public final class CanvasTest extends Application {
private static final int WIDTH = 400;
private static final int HEIGHT = 300;
private static final int RADIUS = 250;
private static final int BRICK_HEIGHT = 15;
private static final int RADIUSHALF = RADIUS / 2;
private static GraphicsContext gc;
@Override
public void start(Stage stage) {
final Group root = new Group();
final Scene scene = new Scene(root, WIDTH, HEIGHT);
final Canvas can = new Canvas(WIDTH, HEIGHT);
gc = can.getGraphicsContext2D();
gc.setFill(Color.BLACK);
gc.fillRect(0, 0, WIDTH, HEIGHT);
drawArc(WIDTH / 2, HEIGHT / 2);
root.getChildren().add(can);
stage.setScene(scene);
stage.show();
}
private void drawArc(final int posX, final int posY) {
gc.setStroke(Color.WHITE);
gc.setLineWidth(1);
gc.setFill(Color.WHITE);
final double newRadius = RADIUSHALF - BRICK_HEIGHT;
final double yOffsetLowerArc = Math.cos(Math.toRadians(45)) * newRadius;
final double xOffsetLowerArc = Math.sin(Math.toRadians(45)) * newRadius;
final double newAngleLowerArc = Math.toDegrees(Math.atan2(xOffsetLowerArc, yOffsetLowerArc + BRICK_HEIGHT));
final double xOffsetUpperArc = Math.cos(Math.toRadians(45)) * RADIUSHALF;
final double yOffsetUpperArc = Math.sin(Math.toRadians(45)) * RADIUSHALF;
final double yOffsetNewLowerArc = Math.cos(Math.toRadians(newAngleLowerArc)) * RADIUSHALF;
final double xOffsetNewLowerArc = Math.sin(Math.toRadians(newAngleLowerArc)) * RADIUSHALF;
// this code produces the un-filled custom arc
// gc.strokeArc(posX - RADIUSHALF, posY - RADIUSHALF, RADIUS, RADIUS, 45, 90, ArcType.OPEN);
// gc.strokeArc(posX - RADIUSHALF, posY - RADIUSHALF + BRICK_HEIGHT, RADIUS, RADIUS, 90 - newAngleLowerArc, 2 * newAngleLowerArc, ArcType.OPEN);
// gc.strokeLine(posX - xOffsetNewLowerArc, posY + BRICK_HEIGHT - yOffsetNewLowerArc, posX - xOffsetUpperArc, posY - yOffsetUpperArc);
// gc.strokeLine(posX + xOffsetNewLowerArc, posY + BRICK_HEIGHT - yOffsetNewLowerArc, posX + xOffsetUpperArc, posY - yOffsetUpperArc);
gc.beginPath();
gc.arc(posX - RADIUSHALF, posY - RADIUSHALF, RADIUS, RADIUS, 45, 90/*, ArcType.OPEN*/);
gc.arc(posX - RADIUSHALF, posY - RADIUSHALF + BRICK_HEIGHT, RADIUS, RADIUS, 90 - newAngleLowerArc, 2 * newAngleLowerArc/*, ArcType.OPEN*/);
gc.moveTo(posX + xOffsetNewLowerArc, posY + BRICK_HEIGHT - yOffsetNewLowerArc);
gc.lineTo(posX + xOffsetUpperArc, posY - yOffsetUpperArc);
gc.moveTo(posX - xOffsetNewLowerArc, posY + BRICK_HEIGHT - yOffsetNewLowerArc);
gc.lineTo(posX - xOffsetUpperArc, posY - yOffsetUpperArc);
gc.closePath();
gc.fill();
}
public static void main(String[] args) {
Application.launch(args);
}
}
也许我也误解了JavaFX中路径的概念,但对我来说,我的方法是合理的:-)但它不起作用。 (我还读过这篇“Working with Canvas”)
最佳答案
您的代码存在一些问题。 GraphicsContext.arc
的参数与 GraphicsContext.strokeArc
不同.
strokeArc(double x,
double y,
double w,
double h,
double startAngle,
double arcExtent,
ArcType closure)
arc(double centerX,
double centerY,
double radiusX,
double radiusY,
double startAngle,
double length)
区别是:strokeArc
在位于点 (x, y)
的矩形中绘制属于椭圆形一部分的圆弧给定width
和height
。 arc
然而,构造了一条路径,该路径是以 (centerX, centerY)
为中心的椭圆形的一部分。半径 radiusX
和radiusY
。获取 arc
的适当参数您可以使用以下公式:
centerX = (x+w)/2
centerY = (y+h)/2
radiusX = w/2
radiusY = h/2
而且您不需要调用moveTo
来构建路径。 2 条弧足以构建路径。还要确保使用不同方向的弧(一个顺时针一个逆时针)来连接弧的最近端:
gc.beginPath();
gc.arc(posX, posY, RADIUSHALF, RADIUSHALF, 45, 90);
// next arc in opposite direction
gc.arc(posX, posY + BRICK_HEIGHT, RADIUSHALF, RADIUSHALF, 90 + newAngleLowerArc, -2 * newAngleLowerArc);
gc.closePath();
gc.fill();
关于JavaFX Canvas : fill closed path composed of multiple geometries,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33369661/