8

JavaFXで半円を描く方法を教えてください。ShapeとQuadCurveを使用しようとしましたが、完全な半円を作成できませんでした。

これが私が描き込もうとしているものの写真です:

ここに画像の説明を入力してください

4

4 に答える 4

13

リンクした画像は実際には半環です。ネストされた2つの円弧といくつかの線を描画することにより、JavaFXで取得できます。しかし、私の好みの方法はを使用することPathです。

public class SemiDemo extends Application {

    @Override
    public void start(Stage primaryStage) {

        Group root = new Group();
        root.getChildren().add(drawSemiRing(120, 120, 100, 50, Color.LIGHTGREEN, Color.DARKGREEN));
        root.getChildren().add(drawSemiRing(350, 350, 200, 30, Color.LIGHTSKYBLUE, Color.DARKBLUE));

        Scene scene = new Scene(root, 300, 250);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private Path drawSemiRing(double centerX, double centerY, double radius, double innerRadius, Color bgColor, Color strkColor) {
        Path path = new Path();
        path.setFill(bgColor);
        path.setStroke(strkColor);
        path.setFillRule(FillRule.EVEN_ODD);

        MoveTo moveTo = new MoveTo();
        moveTo.setX(centerX + innerRadius);
        moveTo.setY(centerY);

        ArcTo arcToInner = new ArcTo();
        arcToInner.setX(centerX - innerRadius);
        arcToInner.setY(centerY);
        arcToInner.setRadiusX(innerRadius);
        arcToInner.setRadiusY(innerRadius);

        MoveTo moveTo2 = new MoveTo();
        moveTo2.setX(centerX + innerRadius);
        moveTo2.setY(centerY);

        HLineTo hLineToRightLeg = new HLineTo();
        hLineToRightLeg.setX(centerX + radius);

        ArcTo arcTo = new ArcTo();
        arcTo.setX(centerX - radius);
        arcTo.setY(centerY);
        arcTo.setRadiusX(radius);
        arcTo.setRadiusY(radius);

        HLineTo hLineToLeftLeg = new HLineTo();
        hLineToLeftLeg.setX(centerX - innerRadius);

        path.getElements().add(moveTo);
        path.getElements().add(arcToInner);
        path.getElements().add(moveTo2);
        path.getElements().add(hLineToRightLeg);
        path.getElements().add(arcTo);
        path.getElements().add(hLineToLeftLeg);

        return path;
    }

    public static void main(String[] args) {
        launch(args);
    }
}

コードで使用される形状の詳細については、JavaFXのShapeAPIを参照してください。
スクリーンショット:

ここに画像の説明を入力してください

于 2012-07-30T11:44:56.000 に答える
4

提案:

  • 完全なアウトラインパスが必要ない場合は、Arcを使用できます。
  • 円弧を塗りつぶす必要がなく、円弧のアウトラインパスをトレースするだけの場合は、円弧の塗りつぶしをnullに設定します。
  • 円弧のアウトラインパスを太くしたい場合は、円弧のストロークパラメータを設定します。
  • 輪郭が描かれている太い弧が必要な場合は、Ulukの答えのように完全な弧を定義するのが最善です。

サンプルコード:

import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.stage.Stage;

public class SemiCircleSample extends Application {
  @Override public void start(Stage stage) {
    Arc arc = new Arc(50, 50, 25, 25, 0, 180);
    arc.setType(ArcType.OPEN);
    arc.setStrokeWidth(10);
    arc.setStroke(Color.CORAL);
    arc.setStrokeType(StrokeType.INSIDE);
    arc.setFill(null);

    stage.setScene(new Scene(new Group(arc), 100, 80));
    stage.show();
  }

  public static void main(String[] args) { launch(args); }
}
于 2012-07-30T10:50:18.573 に答える
2

実験として、Canvasで同じことをしようとしました。これは、RadialGradientと関数GraphicsContext.fillArcを使用して私が思いついたものです。

/**
 *
 * @param x Coordinate x of the centre of the arc
 * @param y Coordinate y of the centre of the arc
 * @param outer Outer radius of the arc
 * @param innerPercentage Inner radius of the arc, from 0 to 1 (as percentage)
 * @param arcStartAngle Start angle of the arc, in degrees
 * @param arcExtent Extent of the arc, in degrees
 */
private void drawSemiCircle(float x, float y, float outer, float innerPercentage, float arcStartAngle, float arcExtent) {
    RadialGradient rg = new RadialGradient(
            0,
            0,
            x,
            y,
            outer,
            false,
            CycleMethod.NO_CYCLE,
            new Stop((innerPercentage + (.0 * innerPercentage)), Color.TRANSPARENT),
            new Stop((innerPercentage + (.1 * innerPercentage)), Color.RED),
            new Stop((innerPercentage + (.6 * innerPercentage)), Color.YELLOW),
            new Stop((innerPercentage + (1 * innerPercentage)), Color.GREEN)
    );
    gc.setFill(rg);
    gc.fillArc(
            x - outer,
            y - outer,
            outer * 2,
            outer * 2,
            arcStartAngle,
            arcExtent,
            ArcType.ROUND
    );
}

ここでの重要なポイントは、ArcType.ROUNDとしてのアークタイプと、最初の色としてのColor.TRANSPARENTの使用です。

次に、それは線に沿って何かを使用することができます:

drawSemiCircle(100, 100, 100, .5f, -45, 270);

それは完璧な解決策ではありませんが、私にとってはうまくいきました。

于 2018-02-28T23:43:37.297 に答える
0

Path.arcTo()パラメータSweepAngleは回転角度を参照します。sweepAngleが正の場合、円弧は時計回りです。sweepAngleが負の場合、円弧は反時計回りです。

このコードは私の実稼働環境で使用され、ビットマップイメージを使用して半円のリングを描画し、パスは外側の半径を時計回りに、内側の半径を反時計回りに進みます。

drawpercent = 0.85; //this draws a semi ring to 85% you can change it using your code.
DegreesStart = -90;
DegreesRotation = 180;

radiusPathRectF = new android.graphics.RectF((float)CentreX - (float)Radius, (float)CentreY - (float)Radius,  (float)CentreX + (float)Radius, (float)CentreY + (float)Radius);
innerradiusPathRectF = new android.graphics.RectF((float)CentreX - (float)InnerRadius, (float)CentreY - (float)InnerRadius, (float)CentreX + (float)InnerRadius, (float)CentreY + (float)InnerRadius);

Path p = new Path(); //TODO put this outside your draw() function,  you should never have a "new" keyword inside a fast loop.

                degrees = (360 + (DegreesStart)) % 360;
                radians = (360 - degrees + 90) * Math.PI / 180.0;
                //radians = Math.toRadians(DegreesStart);
                int XstartOuter = (int)Math.round((Math.cos(radians) * Radius + CentreX));
                int YstartOuter = (int)Math.round((Math.sin(-radians)* Radius + CentreY));
                int XstartInner = (int)Math.round((Math.cos(radians) * InnerRadius + CentreX));
                int YstartInner = (int)Math.round((Math.sin(-radians) * InnerRadius + CentreY));

                degrees = (360 + (DegreesStart + drawpercent * DegreesRotation)) % 360;
                //radians = degrees * Math.PI / 180.0;
                radians = (360 - degrees + 90) * Math.PI / 180.0;
                //radians = Math.toRadians(DegreesStart + drawpercent * DegreesRotation);
                int XendOuter = (int)Math.round((Math.cos(radians) * Radius + CentreX));
                int YendOuter = (int)Math.round((Math.sin(-radians) * Radius + CentreY));
                int XendInner = (int)Math.round((Math.cos(radians) * InnerRadius + CentreX));
                int YendInner = (int)Math.round((Math.sin(-radians) * InnerRadius + CentreY));

                //draw a path outlining the semi-circle ring.
                p.moveTo(XstartInner, YstartInner);
                p.lineTo(XstartOuter, YstartOuter);
                p.arcTo(radiusPathRectF, (float)DegreesStart - (float)90, (float)drawpercent * (float)DegreesRotation);
                p.lineTo(XendInner, YendInner);
                p.arcTo(innerradiusPathRectF, (float)degrees - (float)90, -1 * (float)drawpercent * (float)DegreesRotation);
                p.close();

                g.clipPath(p);

                g.drawBitmap(bitmapCircularBarImage, bitmapRect0, bitmapRectXY, paint);
于 2015-07-26T00:59:03.143 に答える