Reputation: 299
For example, I have this Path
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.stage.Stage;
public class DivideShape extends javafx.application.Application {
@Override
public void start(Stage primaryStage) {
var path = new Path(new MoveTo(200, 380), new LineTo(0, 300),
new ArcTo(300, 300, 0, 300, 0, false, true), new LineTo(380,
200), new ArcTo(180, 180, 0, 200, 380, false, false));
path.setFill(Color.BLUE);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(new Scene(new Pane(path)));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
And I want to divide it into 5 parts (exactly the same as dividing pizza)
This can be done using Line.
However, this way it will look like 5 objects, but in reality it will still be 1 object.
Is it possible to divide the object into 5 Paths so that I don't have to create them all one by one, please?
Thank you
UPDATE:
Of course, when I modify the start method.
@Override
public void start(Stage primaryStage) {
var pane = new Pane();
var moveTo = new MoveTo(200, 380);
var lineTo = new LineTo(0, 300);
var arc_big = 300;
var arc_small = 180;
for (var deg = 198; deg <= 270; deg += 18) {
var path = new Path(moveTo, lineTo);
lineTo = new LineTo(300 + arc_big * Math.cos(Math.toRadians(deg)), 300 + arc_big * Math.sin(Math.toRadians(deg)));
path.getElements().add(new ArcTo(arc_big, arc_big, 0, lineTo.getX(), lineTo.getY(), false, true));
var move = new MoveTo(380 + arc_small * Math.cos(Math.toRadians(deg)), 380 + arc_small * Math.sin(Math.toRadians(deg)));
path.getElements().addAll(new LineTo(move.getX(), move.getY()),
new ArcTo(arc_small, arc_small, 0, moveTo.getX(), moveTo.getY(), false, false));
moveTo = move;
path.setFill(Color.color(Math.random(), Math.random(), Math.random()));
pane.getChildren().add(path);
}
primaryStage.setTitle("Hello World!");
primaryStage.setScene(new Scene(pane));
primaryStage.show();
}
So I'll create five separate Paths, but the code is too complicated. That's why I wanted to know if it could be divided (1 Object to 5 Objects), please?
Upvotes: 3
Views: 484
Reputation: 18792
When a code becomes too complicated consider refactoring it into short single-responsibility reusable methods:
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 ConvinienceMethodsExample extends Application {
private static final double OUTER_RADIUS =300, INNER_RADIUS = 180, ORIGIN_X = 300, ORIGIN_Y = 300;
private static final double START_ANGLE =20, END_ANGLE = 70, STEP_ANGEL = 10;
@Override
public void start(Stage primaryStage) {
Group group = new Group();
for(double angle = START_ANGLE; angle < END_ANGLE ; angle += STEP_ANGEL ){
Point2D innerArcStart = getPoint(INNER_RADIUS, angle);
Point2D innerArcEnd = getPoint(INNER_RADIUS, angle + STEP_ANGEL);
Point2D outerArcStart = getPoint(OUTER_RADIUS, angle);
Point2D outerArcEnd = getPoint(OUTER_RADIUS, angle + STEP_ANGEL);
var path = getPath(innerArcStart, innerArcEnd, outerArcStart, outerArcEnd);
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);
}
}
Upvotes: 5
Reputation: 2569
you can do it with Arc object instead of Path
in this code i've made five arcs of 18 degrees each one and a fade animation to make transparent the path . when the animation ends i remove path from pane children
`
package dividedshape;
import javafx.animation.FadeTransition;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.stage.Stage;
import javafx.util.Duration;
public class DivideShape extends Application {
@Override
public void start(Stage primaryStage) {
Path path = new Path(new MoveTo(500, 500), new LineTo(0, 500),
new ArcTo(500, 500, 0, 500, 0, false, true), new LineTo(500,
500));
path.setFill(Color.BLUE);
Arc arc1 = new Arc(500,500,500,500,90,18);
arc1.setType(ArcType.ROUND);
arc1.setFill(Color.BLUE);
arc1.setStroke(Color.BLACK);
Arc arc2 = new Arc(500,500,500,500,108,18);
arc2.setType(ArcType.ROUND);
arc2.setFill(Color.BLUE);
arc2.setStroke(Color.BLACK);
Arc arc3 = new Arc(500,500,500,500,126,18);
arc3.setType(ArcType.ROUND);
arc3.setFill(Color.BLUE);
arc3.setStroke(Color.BLACK);
Arc arc4 = new Arc(500,500,500,500,144,18);
arc4.setType(ArcType.ROUND);
arc4.setFill(Color.BLUE);
arc4.setStroke(Color.BLACK);
Arc arc5 = new Arc(500,500,500,500,162,18);
arc5.setType(ArcType.ROUND);
arc5.setFill(Color.BLUE);
arc5.setStroke(Color.BLACK);
primaryStage.setTitle("Hello World!");
Pane pane = new Pane(arc1,arc2,arc3,arc4,arc5,path);
primaryStage.setScene(new Scene(pane));
primaryStage.show();
FadeTransition fadePath = new FadeTransition(Duration.seconds(10), path);
fadePath.setFromValue(10);
fadePath.setToValue(0);
fadePath.play();
fadePath.setOnFinished(e->{ pane.getChildren().remove(path);});
}
public static void main(String[] args) {
launch(args);
}
}`
Upvotes: 1