SlideShare a Scribd company logo
Create a java project that:
- Draw a circle with three random initial points on the circle.
- Link the points to form a triangle.
- Print the angles values in the triangle.
- Use the mouse to drag a point along the perimeter of the circle. As you drag it, the triangle and
angles are redisplayed dynamically.
Here is the formula to compute angles:
A = acos((a * a - b * b - c * c) / (-2 * b * c))
B = acos((b * b - a * a - c * c) / (-2 * a * c))
C = acos((c * c - b * b - a * a) / (-2 * a * b))
Solution
@Suppresswarnings("WeakerAccess")
public class DragPoints extends Application {
@Override
public void start(Stage primaryStage) {
final PointPane pane = new PointPane(640, 480);
pane.setStyle("-fx-background-color: wheat;");
Label label = new Label("Click and drag the points.");
BorderPane borderPane = new BorderPane(pane);
BorderPane.setAlignment(label, Pos.CENTER);
label.setPadding(new Insets(5));
borderPane.setBottom(label);
Scene scene = new Scene(borderPane);
primaryStage.setTitle("Exercise15_21");
primaryStage.setScene(scene);
primaryStage.show();
}
private class PointPane extends Pane {
final Circle circle = new Circle();
final Vertex[] v = new Vertex[3];
final int strokeWidth = 2;
final Color circleStroke = Color.GRAY, legStroke = Color.BLACK;
@SuppressWarnings("SameParameterValue")
PointPane(double w, double h) {
this.setPrefSize(w, h);
this.setWidth(w);
this.setHeight(h);
circle.setStroke(circleStroke);
circle.setFill(Color.TRANSPARENT);
circle.setStrokeWidth(strokeWidth);
circle.radiusProperty().bind(this.heightProperty().multiply(0.4));
circle.centerXProperty().bind(this.widthProperty().divide(2));
circle.centerYProperty().bind(this.heightProperty().divide(2));
this.getChildren().add(circle);
for (int i = 0; i < v.length; i++) {
v[i] = new Vertex(circle, 2 * Math.PI / v.length * (i + Math.random()));
v[i].radiusProperty().bind(circle.radiusProperty().divide(10));
v[i].setPosition();
v[i].setStroke(new Color(i == 0 ? 1 : 0, i == 1 ? 1 : 0, i == 2 ? 1 : 0, 1));
v[i].setFill(Color.TRANSPARENT);
v[i].setStrokeWidth(strokeWidth);
this.getChildren().add(v[i]);
v[i].setOnMouseDragged(new EventHandler() {
@Override
public void handle(MouseEvent event) {
int i;
for (i = 0; i < v.length; i++)
if (v[i] == event.getSource())
break;
v[i].setAngle(event.getX(), event.getY());
moveUpdate((Vertex) event.getSource());
}
});
}
for (int i = 0; i < v.length; i++) {
int j = i + 1 < v.length ? i + 1 : 0;
int k = j + 1 < v.length ? j + 1 : 0;
v[i].bindLeg(v[j], v[k]);
v[i].leg.setStroke(legStroke);
v[i].leg.setStrokeWidth(strokeWidth);
this.getChildren().add(v[i].leg);
this.getChildren().add(v[i].text);
}
for(DoubleProperty p: new DoubleProperty[]
{circle.radiusProperty(), circle.centerXProperty(), circle.centerYProperty()})
p.addListener(new ResizeListener());
moveUpdate(v[0]);
}
void moveUpdate(Vertex vert) {
vert.setPosition();
double[] legLength = new double[3];
for (int i = 0; i < v.length; i++)
legLength[i] = v[i].getLegLength();
for (int i = 0; i < v.length; i++) {
int j = i + 1 < v.length ? i + 1 : 0;
int k = j + 1 < v.length ? j + 1 : 0;
double a = legLength[i], b = legLength[j], c = legLength[k];
double d = Math.toDegrees(Math.acos((a * a - b * b - c * c) / (-2 * b * c)));
v[i].setText(d);
}
}
private class ResizeListener implements ChangeListener {
@Override
public void changed(ObservableValue observableValue, Number oldWidth, Number
newWidth) {
for (Vertex aV : v) {
aV.setPosition();
}
}
}
}
private class Vertex extends Circle {
final Circle circle;
final Line leg;
final Text text;
double centerAngle;
Vertex(Circle circle, double centerAngle) {
this.circle = circle;
this.setAngle(centerAngle);
this.leg = new Line();
this.text = new Text();
this.text.setFont(Font.font(20));
this.text.setStroke(Color.BLACK);
this.text.setTextAlignment(TextAlignment.CENTER);
this.text.xProperty().bind(this.centerXProperty().add(25));
this.text.yProperty().bind(this.centerYProperty().subtract(10));
}
double getCenterAngle() {return this.centerAngle;}
void setPosition() {
this.setCenterX(circle.getCenterX() + circle.getRadius() *
Math.cos(this.getCenterAngle()));
this.setCenterY(circle.getCenterY() + circle.getRadius() *
Math.sin(this.getCenterAngle()));
}
void setAngle(double centerAngle) {
this.centerAngle = centerAngle;
}
void setAngle(double x, double y) {
this.setAngle(Math.atan2(y - circle.getCenterY(), x - circle.getCenterX()));
}
void bindLeg(Vertex v1, Vertex v2) {
leg.startXProperty().bind(v1.centerXProperty());
leg.startYProperty().bind(v1.centerYProperty());
leg.endXProperty().bind(v2.centerXProperty());
leg.endYProperty().bind(v2.centerYProperty());
}
double getLegLength() {
return Math.sqrt(Math.pow(leg.getStartX()-leg.getEndX(),2) +
Math.pow(leg.getStartY()-leg.getEndY(),2));
}
void setText(double angle) {
this.text.setText(String.format("%.0fu00B0", angle));
}
}
}
@Suppresswarnings("WeakerAccess")
public class DragPoints extends Application {
@Override
public void start(Stage primaryStage) {
final PointPane pane = new PointPane(640, 480);
pane.setStyle("-fx-background-color: wheat;");
Label label = new Label("Click and drag the points.");
BorderPane borderPane = new BorderPane(pane);
BorderPane.setAlignment(label, Pos.CENTER);
label.setPadding(new Insets(5));
borderPane.setBottom(label);
Scene scene = new Scene(borderPane);
primaryStage.setTitle("Exercise15_21");
primaryStage.setScene(scene);
primaryStage.show();
}
private class PointPane extends Pane {
final Circle circle = new Circle();
final Vertex[] v = new Vertex[3];
final int strokeWidth = 2;
final Color circleStroke = Color.GRAY, legStroke = Color.BLACK;
@SuppressWarnings("SameParameterValue")
PointPane(double w, double h) {
this.setPrefSize(w, h);
this.setWidth(w);
this.setHeight(h);
circle.setStroke(circleStroke);
circle.setFill(Color.TRANSPARENT);
circle.setStrokeWidth(strokeWidth);
circle.radiusProperty().bind(this.heightProperty().multiply(0.4));
circle.centerXProperty().bind(this.widthProperty().divide(2));
circle.centerYProperty().bind(this.heightProperty().divide(2));
this.getChildren().add(circle);
for (int i = 0; i < v.length; i++) {
v[i] = new Vertex(circle, 2 * Math.PI / v.length * (i + Math.random()));
v[i].radiusProperty().bind(circle.radiusProperty().divide(10));
v[i].setPosition();
v[i].setStroke(new Color(i == 0 ? 1 : 0, i == 1 ? 1 : 0, i == 2 ? 1 : 0, 1));
v[i].setFill(Color.TRANSPARENT);
v[i].setStrokeWidth(strokeWidth);
this.getChildren().add(v[i]);
v[i].setOnMouseDragged(new EventHandler() {
@Override
public void handle(MouseEvent event) {
int i;
for (i = 0; i < v.length; i++)
if (v[i] == event.getSource())
break;
v[i].setAngle(event.getX(), event.getY());
moveUpdate((Vertex) event.getSource());
}
});
}
for (int i = 0; i < v.length; i++) {
int j = i + 1 < v.length ? i + 1 : 0;
int k = j + 1 < v.length ? j + 1 : 0;
v[i].bindLeg(v[j], v[k]);
v[i].leg.setStroke(legStroke);
v[i].leg.setStrokeWidth(strokeWidth);
this.getChildren().add(v[i].leg);
this.getChildren().add(v[i].text);
}
for(DoubleProperty p: new DoubleProperty[]
{circle.radiusProperty(), circle.centerXProperty(), circle.centerYProperty()})
p.addListener(new ResizeListener());
moveUpdate(v[0]);
}
void moveUpdate(Vertex vert) {
vert.setPosition();
double[] legLength = new double[3];
for (int i = 0; i < v.length; i++)
legLength[i] = v[i].getLegLength();
for (int i = 0; i < v.length; i++) {
int j = i + 1 < v.length ? i + 1 : 0;
int k = j + 1 < v.length ? j + 1 : 0;
double a = legLength[i], b = legLength[j], c = legLength[k];
double d = Math.toDegrees(Math.acos((a * a - b * b - c * c) / (-2 * b * c)));
v[i].setText(d);
}
}
private class ResizeListener implements ChangeListener {
@Override
public void changed(ObservableValue observableValue, Number oldWidth, Number
newWidth) {
for (Vertex aV : v) {
aV.setPosition();
}
}
}
}
private class Vertex extends Circle {
final Circle circle;
final Line leg;
final Text text;
double centerAngle;
Vertex(Circle circle, double centerAngle) {
this.circle = circle;
this.setAngle(centerAngle);
this.leg = new Line();
this.text = new Text();
this.text.setFont(Font.font(20));
this.text.setStroke(Color.BLACK);
this.text.setTextAlignment(TextAlignment.CENTER);
this.text.xProperty().bind(this.centerXProperty().add(25));
this.text.yProperty().bind(this.centerYProperty().subtract(10));
}
double getCenterAngle() {return this.centerAngle;}
void setPosition() {
this.setCenterX(circle.getCenterX() + circle.getRadius() *
Math.cos(this.getCenterAngle()));
this.setCenterY(circle.getCenterY() + circle.getRadius() *
Math.sin(this.getCenterAngle()));
}
void setAngle(double centerAngle) {
this.centerAngle = centerAngle;
}
void setAngle(double x, double y) {
this.setAngle(Math.atan2(y - circle.getCenterY(), x - circle.getCenterX()));
}
void bindLeg(Vertex v1, Vertex v2) {
leg.startXProperty().bind(v1.centerXProperty());
leg.startYProperty().bind(v1.centerYProperty());
leg.endXProperty().bind(v2.centerXProperty());
leg.endYProperty().bind(v2.centerYProperty());
}
double getLegLength() {
return Math.sqrt(Math.pow(leg.getStartX()-leg.getEndX(),2) +
Math.pow(leg.getStartY()-leg.getEndY(),2));
}
void setText(double angle) {
this.text.setText(String.format("%.0fu00B0", angle));
}
}
}

More Related Content

PDF
package chapter15;import javafx.application.Application;import j.pdf
KEY
openFrameworks 007 - 3D
DOCX
PDF
need help with code I wrote. This code is a maze gui, and i need hel.pdf
PDF
I wanna add the shape creator like rectangular , square , circle etc.pdf
PDF
Computer Graphics in Java and Scala - Part 1b
PDF
Mini-curso JavaFX Aula2
PDF
S'il te plait, dessine moi une vue
package chapter15;import javafx.application.Application;import j.pdf
openFrameworks 007 - 3D
need help with code I wrote. This code is a maze gui, and i need hel.pdf
I wanna add the shape creator like rectangular , square , circle etc.pdf
Computer Graphics in Java and Scala - Part 1b
Mini-curso JavaFX Aula2
S'il te plait, dessine moi une vue

More from arihantmobileselepun (20)

PDF
How are the epimysium and tendons relatedA. The epimysium surroun.pdf
PDF
How does DNA differ from RNAA. RNA uses only purinesB. RNA uses.pdf
PDF
Gerard throws a discus distances of 10 meters, 14.5 meters, 14.8 met.pdf
PDF
For Printing and personal use ONLY. DO NOT Hand in this copy of the a.pdf
PDF
Find and provide a link to a multi-year capital plan from any Illino.pdf
PDF
A geneticist is working with a new bacteriophage called phage Y3 that.pdf
PDF
Assume that the four living species in the figure below evolved from.pdf
PDF
Declining BalanceThe cost of the asset $10,000.00 The salvage v.pdf
PDF
aphase The spindle contracts and the sister chromatids are separated.pdf
PDF
A population of wild deer mice includes individuals with long or sho.pdf
PDF
Who is it important that the lymphatic system operate separately f.pdf
PDF
Provide a full explanation to the below question.1. Summarize the .pdf
PDF
Write a program to generate the entire calendar for one year. The pr.pdf
PDF
Write the interval notation for the set of numbers graphed. Solu.pdf
PDF
Why doesnt hemoglobin have any intermediate conformations between .pdf
PDF
4. What is gyanandromorphy How does this happenSolutionAnswe.pdf
PDF
Which of the following requires the mitochondria to create contact po.pdf
PDF
why nitrogen fixation is so importantSolutionNitrogen fixation.pdf
PDF
what will happen to the photon if two photons enter the same atom si.pdf
PDF
Which of the following is not a function of the skeletonA. Storag.pdf
How are the epimysium and tendons relatedA. The epimysium surroun.pdf
How does DNA differ from RNAA. RNA uses only purinesB. RNA uses.pdf
Gerard throws a discus distances of 10 meters, 14.5 meters, 14.8 met.pdf
For Printing and personal use ONLY. DO NOT Hand in this copy of the a.pdf
Find and provide a link to a multi-year capital plan from any Illino.pdf
A geneticist is working with a new bacteriophage called phage Y3 that.pdf
Assume that the four living species in the figure below evolved from.pdf
Declining BalanceThe cost of the asset $10,000.00 The salvage v.pdf
aphase The spindle contracts and the sister chromatids are separated.pdf
A population of wild deer mice includes individuals with long or sho.pdf
Who is it important that the lymphatic system operate separately f.pdf
Provide a full explanation to the below question.1. Summarize the .pdf
Write a program to generate the entire calendar for one year. The pr.pdf
Write the interval notation for the set of numbers graphed. Solu.pdf
Why doesnt hemoglobin have any intermediate conformations between .pdf
4. What is gyanandromorphy How does this happenSolutionAnswe.pdf
Which of the following requires the mitochondria to create contact po.pdf
why nitrogen fixation is so importantSolutionNitrogen fixation.pdf
what will happen to the photon if two photons enter the same atom si.pdf
Which of the following is not a function of the skeletonA. Storag.pdf
Ad

Recently uploaded (20)

PDF
Computing-Curriculum for Schools in Ghana
PDF
Black Hat USA 2025 - Micro ICS Summit - ICS/OT Threat Landscape
PPTX
Microbial diseases, their pathogenesis and prophylaxis
PPTX
BOWEL ELIMINATION FACTORS AFFECTING AND TYPES
PDF
Complications of Minimal Access Surgery at WLH
PDF
102 student loan defaulters named and shamed – Is someone you know on the list?
PDF
Sports Quiz easy sports quiz sports quiz
PDF
2.FourierTransform-ShortQuestionswithAnswers.pdf
PPTX
Cell Types and Its function , kingdom of life
PDF
Abdominal Access Techniques with Prof. Dr. R K Mishra
PPTX
PPT- ENG7_QUARTER1_LESSON1_WEEK1. IMAGERY -DESCRIPTIONS pptx.pptx
PDF
BÀI TẬP BỔ TRỢ 4 KỸ NĂNG TIẾNG ANH 9 GLOBAL SUCCESS - CẢ NĂM - BÁM SÁT FORM Đ...
PPTX
master seminar digital applications in india
PDF
Classroom Observation Tools for Teachers
PPTX
Final Presentation General Medicine 03-08-2024.pptx
PDF
Chapter 2 Heredity, Prenatal Development, and Birth.pdf
PDF
Physiotherapy_for_Respiratory_and_Cardiac_Problems WEBBER.pdf
PPTX
PPH.pptx obstetrics and gynecology in nursing
PPTX
Cell Structure & Organelles in detailed.
PDF
VCE English Exam - Section C Student Revision Booklet
Computing-Curriculum for Schools in Ghana
Black Hat USA 2025 - Micro ICS Summit - ICS/OT Threat Landscape
Microbial diseases, their pathogenesis and prophylaxis
BOWEL ELIMINATION FACTORS AFFECTING AND TYPES
Complications of Minimal Access Surgery at WLH
102 student loan defaulters named and shamed – Is someone you know on the list?
Sports Quiz easy sports quiz sports quiz
2.FourierTransform-ShortQuestionswithAnswers.pdf
Cell Types and Its function , kingdom of life
Abdominal Access Techniques with Prof. Dr. R K Mishra
PPT- ENG7_QUARTER1_LESSON1_WEEK1. IMAGERY -DESCRIPTIONS pptx.pptx
BÀI TẬP BỔ TRỢ 4 KỸ NĂNG TIẾNG ANH 9 GLOBAL SUCCESS - CẢ NĂM - BÁM SÁT FORM Đ...
master seminar digital applications in india
Classroom Observation Tools for Teachers
Final Presentation General Medicine 03-08-2024.pptx
Chapter 2 Heredity, Prenatal Development, and Birth.pdf
Physiotherapy_for_Respiratory_and_Cardiac_Problems WEBBER.pdf
PPH.pptx obstetrics and gynecology in nursing
Cell Structure & Organelles in detailed.
VCE English Exam - Section C Student Revision Booklet
Ad

Create a java project that - Draw a circle with three random init.pdf

  • 1. Create a java project that: - Draw a circle with three random initial points on the circle. - Link the points to form a triangle. - Print the angles values in the triangle. - Use the mouse to drag a point along the perimeter of the circle. As you drag it, the triangle and angles are redisplayed dynamically. Here is the formula to compute angles: A = acos((a * a - b * b - c * c) / (-2 * b * c)) B = acos((b * b - a * a - c * c) / (-2 * a * c)) C = acos((c * c - b * b - a * a) / (-2 * a * b)) Solution @Suppresswarnings("WeakerAccess") public class DragPoints extends Application { @Override public void start(Stage primaryStage) { final PointPane pane = new PointPane(640, 480); pane.setStyle("-fx-background-color: wheat;"); Label label = new Label("Click and drag the points."); BorderPane borderPane = new BorderPane(pane); BorderPane.setAlignment(label, Pos.CENTER); label.setPadding(new Insets(5)); borderPane.setBottom(label); Scene scene = new Scene(borderPane); primaryStage.setTitle("Exercise15_21"); primaryStage.setScene(scene); primaryStage.show(); } private class PointPane extends Pane { final Circle circle = new Circle(); final Vertex[] v = new Vertex[3]; final int strokeWidth = 2; final Color circleStroke = Color.GRAY, legStroke = Color.BLACK; @SuppressWarnings("SameParameterValue")
  • 2. PointPane(double w, double h) { this.setPrefSize(w, h); this.setWidth(w); this.setHeight(h); circle.setStroke(circleStroke); circle.setFill(Color.TRANSPARENT); circle.setStrokeWidth(strokeWidth); circle.radiusProperty().bind(this.heightProperty().multiply(0.4)); circle.centerXProperty().bind(this.widthProperty().divide(2)); circle.centerYProperty().bind(this.heightProperty().divide(2)); this.getChildren().add(circle); for (int i = 0; i < v.length; i++) { v[i] = new Vertex(circle, 2 * Math.PI / v.length * (i + Math.random())); v[i].radiusProperty().bind(circle.radiusProperty().divide(10)); v[i].setPosition(); v[i].setStroke(new Color(i == 0 ? 1 : 0, i == 1 ? 1 : 0, i == 2 ? 1 : 0, 1)); v[i].setFill(Color.TRANSPARENT); v[i].setStrokeWidth(strokeWidth); this.getChildren().add(v[i]); v[i].setOnMouseDragged(new EventHandler() { @Override public void handle(MouseEvent event) { int i; for (i = 0; i < v.length; i++) if (v[i] == event.getSource()) break; v[i].setAngle(event.getX(), event.getY()); moveUpdate((Vertex) event.getSource()); } }); } for (int i = 0; i < v.length; i++) { int j = i + 1 < v.length ? i + 1 : 0; int k = j + 1 < v.length ? j + 1 : 0; v[i].bindLeg(v[j], v[k]); v[i].leg.setStroke(legStroke);
  • 3. v[i].leg.setStrokeWidth(strokeWidth); this.getChildren().add(v[i].leg); this.getChildren().add(v[i].text); } for(DoubleProperty p: new DoubleProperty[] {circle.radiusProperty(), circle.centerXProperty(), circle.centerYProperty()}) p.addListener(new ResizeListener()); moveUpdate(v[0]); } void moveUpdate(Vertex vert) { vert.setPosition(); double[] legLength = new double[3]; for (int i = 0; i < v.length; i++) legLength[i] = v[i].getLegLength(); for (int i = 0; i < v.length; i++) { int j = i + 1 < v.length ? i + 1 : 0; int k = j + 1 < v.length ? j + 1 : 0; double a = legLength[i], b = legLength[j], c = legLength[k]; double d = Math.toDegrees(Math.acos((a * a - b * b - c * c) / (-2 * b * c))); v[i].setText(d); } } private class ResizeListener implements ChangeListener { @Override public void changed(ObservableValue observableValue, Number oldWidth, Number newWidth) { for (Vertex aV : v) { aV.setPosition(); } } } } private class Vertex extends Circle { final Circle circle; final Line leg;
  • 4. final Text text; double centerAngle; Vertex(Circle circle, double centerAngle) { this.circle = circle; this.setAngle(centerAngle); this.leg = new Line(); this.text = new Text(); this.text.setFont(Font.font(20)); this.text.setStroke(Color.BLACK); this.text.setTextAlignment(TextAlignment.CENTER); this.text.xProperty().bind(this.centerXProperty().add(25)); this.text.yProperty().bind(this.centerYProperty().subtract(10)); } double getCenterAngle() {return this.centerAngle;} void setPosition() { this.setCenterX(circle.getCenterX() + circle.getRadius() * Math.cos(this.getCenterAngle())); this.setCenterY(circle.getCenterY() + circle.getRadius() * Math.sin(this.getCenterAngle())); } void setAngle(double centerAngle) { this.centerAngle = centerAngle; } void setAngle(double x, double y) { this.setAngle(Math.atan2(y - circle.getCenterY(), x - circle.getCenterX())); } void bindLeg(Vertex v1, Vertex v2) { leg.startXProperty().bind(v1.centerXProperty()); leg.startYProperty().bind(v1.centerYProperty()); leg.endXProperty().bind(v2.centerXProperty()); leg.endYProperty().bind(v2.centerYProperty()); } double getLegLength() { return Math.sqrt(Math.pow(leg.getStartX()-leg.getEndX(),2) + Math.pow(leg.getStartY()-leg.getEndY(),2)); }
  • 5. void setText(double angle) { this.text.setText(String.format("%.0fu00B0", angle)); } } } @Suppresswarnings("WeakerAccess") public class DragPoints extends Application { @Override public void start(Stage primaryStage) { final PointPane pane = new PointPane(640, 480); pane.setStyle("-fx-background-color: wheat;"); Label label = new Label("Click and drag the points."); BorderPane borderPane = new BorderPane(pane); BorderPane.setAlignment(label, Pos.CENTER); label.setPadding(new Insets(5)); borderPane.setBottom(label); Scene scene = new Scene(borderPane); primaryStage.setTitle("Exercise15_21"); primaryStage.setScene(scene); primaryStage.show(); } private class PointPane extends Pane { final Circle circle = new Circle(); final Vertex[] v = new Vertex[3]; final int strokeWidth = 2; final Color circleStroke = Color.GRAY, legStroke = Color.BLACK; @SuppressWarnings("SameParameterValue") PointPane(double w, double h) { this.setPrefSize(w, h); this.setWidth(w); this.setHeight(h); circle.setStroke(circleStroke); circle.setFill(Color.TRANSPARENT); circle.setStrokeWidth(strokeWidth); circle.radiusProperty().bind(this.heightProperty().multiply(0.4)); circle.centerXProperty().bind(this.widthProperty().divide(2));
  • 6. circle.centerYProperty().bind(this.heightProperty().divide(2)); this.getChildren().add(circle); for (int i = 0; i < v.length; i++) { v[i] = new Vertex(circle, 2 * Math.PI / v.length * (i + Math.random())); v[i].radiusProperty().bind(circle.radiusProperty().divide(10)); v[i].setPosition(); v[i].setStroke(new Color(i == 0 ? 1 : 0, i == 1 ? 1 : 0, i == 2 ? 1 : 0, 1)); v[i].setFill(Color.TRANSPARENT); v[i].setStrokeWidth(strokeWidth); this.getChildren().add(v[i]); v[i].setOnMouseDragged(new EventHandler() { @Override public void handle(MouseEvent event) { int i; for (i = 0; i < v.length; i++) if (v[i] == event.getSource()) break; v[i].setAngle(event.getX(), event.getY()); moveUpdate((Vertex) event.getSource()); } }); } for (int i = 0; i < v.length; i++) { int j = i + 1 < v.length ? i + 1 : 0; int k = j + 1 < v.length ? j + 1 : 0; v[i].bindLeg(v[j], v[k]); v[i].leg.setStroke(legStroke); v[i].leg.setStrokeWidth(strokeWidth); this.getChildren().add(v[i].leg); this.getChildren().add(v[i].text); } for(DoubleProperty p: new DoubleProperty[] {circle.radiusProperty(), circle.centerXProperty(), circle.centerYProperty()}) p.addListener(new ResizeListener()); moveUpdate(v[0]);
  • 7. } void moveUpdate(Vertex vert) { vert.setPosition(); double[] legLength = new double[3]; for (int i = 0; i < v.length; i++) legLength[i] = v[i].getLegLength(); for (int i = 0; i < v.length; i++) { int j = i + 1 < v.length ? i + 1 : 0; int k = j + 1 < v.length ? j + 1 : 0; double a = legLength[i], b = legLength[j], c = legLength[k]; double d = Math.toDegrees(Math.acos((a * a - b * b - c * c) / (-2 * b * c))); v[i].setText(d); } } private class ResizeListener implements ChangeListener { @Override public void changed(ObservableValue observableValue, Number oldWidth, Number newWidth) { for (Vertex aV : v) { aV.setPosition(); } } } } private class Vertex extends Circle { final Circle circle; final Line leg; final Text text; double centerAngle; Vertex(Circle circle, double centerAngle) { this.circle = circle; this.setAngle(centerAngle); this.leg = new Line(); this.text = new Text(); this.text.setFont(Font.font(20)); this.text.setStroke(Color.BLACK);
  • 8. this.text.setTextAlignment(TextAlignment.CENTER); this.text.xProperty().bind(this.centerXProperty().add(25)); this.text.yProperty().bind(this.centerYProperty().subtract(10)); } double getCenterAngle() {return this.centerAngle;} void setPosition() { this.setCenterX(circle.getCenterX() + circle.getRadius() * Math.cos(this.getCenterAngle())); this.setCenterY(circle.getCenterY() + circle.getRadius() * Math.sin(this.getCenterAngle())); } void setAngle(double centerAngle) { this.centerAngle = centerAngle; } void setAngle(double x, double y) { this.setAngle(Math.atan2(y - circle.getCenterY(), x - circle.getCenterX())); } void bindLeg(Vertex v1, Vertex v2) { leg.startXProperty().bind(v1.centerXProperty()); leg.startYProperty().bind(v1.centerYProperty()); leg.endXProperty().bind(v2.centerXProperty()); leg.endYProperty().bind(v2.centerYProperty()); } double getLegLength() { return Math.sqrt(Math.pow(leg.getStartX()-leg.getEndX(),2) + Math.pow(leg.getStartY()-leg.getEndY(),2)); } void setText(double angle) { this.text.setText(String.format("%.0fu00B0", angle)); } } }