在JavaFX中绘制等份半环

问题描述 投票:0回答:1

我正在开发一个个人项目,我希望用户能够使用简单版本的径向菜单。我一直在尝试创建一个由 N 个弧(或其他形状)组成的戒指,我希望它看起来类似于甜甜圈/戒指。其中件数以及内半径和外半径可以使用变量进行配置。

我希望最终的结果是一个简单的版本: Helo Wars Radial Menu

我有一些部分工作但看起来很粗糙的东西。这是我迄今为止最好的。下面我附上了我的代码和结果的屏幕截图。我希望每块都围绕内圆大小相等

Current output

另请注意,我看到其他帖子利用增加弧线的宽度,我宁愿不使用它,因为我遇到了鼠标悬停在侦听器上的问题,其中“命中区域”有点偏离。

package com.example.javafx21;


import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Arc;
import javafx.scene.shape.ArcType;
import javafx.stage.Stage;

public class HelloApplication extends Application {

    @Override
    public void start(Stage primaryStage) {
        Pane root = new Pane();
        root.setPrefSize(300, 300);

        double centerX = 150;
        double centerY = 150;


        double innerRadius = 40;
        double outerRadius = 100;

        int numPieces = 8;

        for (int i = 0; i < numPieces; i++) {

            double angle = 360.0 / numPieces * i;

            Arc arc = new Arc();
            arc.setCenterX(centerX);
            arc.setCenterY(centerY);
            arc.setRadiusX(outerRadius);
            arc.setRadiusY(outerRadius);
            arc.setStartAngle(angle);
            arc.setLength((double) 360 / numPieces);
            arc.setType(ArcType.OPEN);
            arc.setStroke(Color.color(Math.random(), Math.random(), Math.random()));
            arc.setStrokeWidth(outerRadius - innerRadius);
            arc.setFill(null);

            root.getChildren().add(arc);
        }

        Scene scene = new Scene(root);

        primaryStage.setTitle("Adjustable Radius Semi-Rings");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

javafx geometry draw trigonometry radial
1个回答
0
投票

这里是一个基于代码这里的示例。我编辑了

INNER_RADIUS
START_ANGLE
END_ANGLE
STEP_ANGLE
。我还添加了一个新变量,
GAP
GAP
是每个段之间的空间。

import javafx.application.Application;
import javafx.geometry.Point2D;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.ArcTo;
import javafx.scene.shape.LineTo;
import javafx.scene.shape.MoveTo;
import javafx.scene.shape.Path;
import javafx.scene.shape.Shape;
import javafx.stage.Stage;

public class App extends Application {

    private static final double OUTER_RADIUS =300, INNER_RADIUS = 140, ORIGIN_X = 300, ORIGIN_Y = 300;
    private static final double START_ANGLE =0, END_ANGLE = 360, STEP_ANGLE = 36;
    private static final double GAP = .5;

    @Override
    public void start(Stage primaryStage) {

        Group group = new Group();

        for(double angle =  START_ANGLE; angle < END_ANGLE ; angle += STEP_ANGLE ){
            Point2D innerArcStart = getPoint(INNER_RADIUS, angle + GAP);
            Point2D innerArcEnd = getPoint(INNER_RADIUS, angle - GAP + STEP_ANGLE);
            Point2D outerArcStart = getPoint(OUTER_RADIUS, angle + GAP);
            Point2D outerArcEnd = getPoint(OUTER_RADIUS, angle - GAP + STEP_ANGLE);
            var path = getPath(innerArcStart, innerArcEnd, outerArcStart, outerArcEnd);
            path.setOnMouseEntered((mouseEnteredEvent) -> {
                path.setScaleX(1.2);
                path.setScaleY(1.2);
            });
            
            path.setOnMouseExited((mouseExitedEvent) -> {
                path.setScaleX(1);
                path.setScaleY(1);
            });            
            group.getChildren().add(path);
        }
        primaryStage.setScene(new Scene(new Pane(group)));
        primaryStage.show();
    }

    private Point2D getPoint(double radius, double angle){

        double x = ORIGIN_X - radius * Math.cos(Math.toRadians(angle));
        double y = ORIGIN_Y - radius * Math.sin(Math.toRadians(angle));
        return new Point2D(x, y);
    }

    private Shape getPath(Point2D innerArcStart, Point2D innerArcEnd, Point2D outerArcStart, Point2D outerArcEnd){
        var path = new Path(
                new MoveTo(innerArcStart.getX(), innerArcStart.getY()),
                new LineTo(outerArcStart.getX(), outerArcStart.getY()), //left line
                new ArcTo(OUTER_RADIUS, OUTER_RADIUS, 0, outerArcEnd.getX(), outerArcEnd.getY(), false, true), //outer arc
                new LineTo(innerArcEnd.getX(),innerArcEnd.getY()), //right line
                new ArcTo(INNER_RADIUS, INNER_RADIUS, 0, innerArcStart.getX(), innerArcStart.getY(), false, false)
                );
        path.setFill(Color.color(Math.random(), Math.random(), Math.random()));
        return path;
    }

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

输出

© www.soinside.com 2019 - 2024. All rights reserved.