title: JavaFX Canvas: fill closed path composed of multiple geometries
body: <p>I want draw and fill a path made up of 2 arcs and 2 lines with a specific color. I need to use the Canvas from JavaFX, because there is more i need to draw. The problem is, that the path which I created is not even drawn nor filled. What I want is this</p>
  
  <p><a href="https://i.stack.imgur.com/v41fs.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/v41fs.png" alt="enter image description here"></a></p>
  
  <p>but my code produces this </p>
  
  <p><a href="https://i.stack.imgur.com/w38iy.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/w38iy.png" alt="enter image description here"></a></p>
  
  <p>As you may notice this arc is thinner on the left and on the right side than it is in the middle. Just using a simple arc with a ceratin stroke width is unfortuneatly not an option for me. </p>
  
  <p>This is my code where the commented part produces the second image. I already tried to use the draw path facilities and to fill it, but it is not working</p>
  
  <pre><code>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);
      }
  }
  </code></pre>
  
  <p>Maybe I also misunderstood the concept of paths in JavaFX, but for me my approch is sound :-) never the less it is not working. (I also read this "<a href="http://docs.oracle.com/javafx/2/canvas/jfxpub-canvas.htm" rel="nofollow noreferrer">Working with Canvas</a>")</p>