版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/haoranhaoshi/article/details/82977354
package application;
import java.awt.Point;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.shape.Line;
public class RandomArc extends Application {
@Override
public void start(Stage primaryStage) {
try {
BorderPane root = new BorderPane();
setLines(root, 0, 0, 1000, 500);
Scene scene = new Scene(root, 500, 500);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
private void setLines(Pane pane, int startX, int startY, int endX, int endY) {
//随机产生凹凸个数,2-4
int arcNum = new Random().nextInt(3) + 2;
System.out.println("arcNum:" + arcNum);
int arcStartX = startX,arcStartY = startY;
int isLeftInt = new Random().nextInt(2);
boolean isLeftBoolean = false;
if(isLeftInt == 1){
isLeftBoolean = true;
}
int yChange = 0;
for(int i = 0;i < arcNum;i++){
int arcEndY;
int arcEndX;
if(i == arcNum - 1){
arcEndY = endY;
arcEndX = endX;
}else{
//随机产生两点直线间的分割点
yChange += new Random().nextInt(Math.abs(endY - startY)/2) + Math.abs(endY - startY)/10;
if(endY > startY){
arcEndY = startY + yChange;
}else{
arcEndY = startY - yChange;
}
int xChange = (int)(yChange*1.0/Math.abs(endY - startY)*Math.abs(endX - startX));
System.out.println("yChange:" + yChange + "---xChange:" + xChange);
if(endX > startX){
arcEndX = startX + xChange;
}else{
arcEndX = startX - xChange;
}
}
System.out.println("arcEndY:" + arcEndY + "---arcEndX:" + arcEndX);
if(((endX > startX)&&(arcEndX > endX)) || ((endY > startY)&&(arcEndY > endY)) || ((endX < startX)&&(arcEndX < endX)) || ((endY < startY)&&(arcEndY < endY))){
arcEndX = endX;
arcEndY = endY;
setGroup(pane, arcStartX, arcStartY, arcEndX, arcEndY,isLeftBoolean);
return;
}
setGroup(pane, arcStartX, arcStartY, arcEndX, arcEndY,isLeftBoolean);
isLeftBoolean = !isLeftBoolean;
System.out.println("isLeftBoolean:" + isLeftBoolean);
arcStartX = arcEndX;
arcStartY = arcEndY;
}
}
//生成一段贝叶斯曲线
private void setGroup(Pane pane, int startX, int startY, int endX, int endY, boolean isLeft){
Point controlPoint;
if(isLeft){
//从左下至右上时,向左凸
controlPoint = new Point(startX + (endX - startX)/2, endY);
}else{
//从左下至右上时,向左凸
controlPoint = new Point(endX, startY + (endY - startY)/2);
}
List<Point> bezier = bezier(new Point(startX, startY), controlPoint,
new Point(endX, endY));
for (int i = 0; i < bezier.size() - 1; i++) {
Line line = new Line(bezier.get(i).x, bezier.get(i).y, bezier.get(i + 1).x, bezier.get(i + 1).y);
pane.getChildren().add(line);
}
}
//一段贝塞尔曲线的点的集合
private List<Point> bezier(Point startPoint, Point controlPoint, Point endPoint) {
//steps为一段贝塞尔曲线上的点,点越多越圆滑
int steps = 20;
List<Point> list = new ArrayList<Point>();
float tStep = 1 / ((float) steps);
float t = 0f;
for (int ik = 0; ik <= steps; ik++) {
int x = (int) calculateQuadSpline(startPoint.x, controlPoint.x, endPoint.x, t);
int y = (int) calculateQuadSpline(startPoint.y, controlPoint.y, endPoint.y, t);
list.add(new Point(x, y));
t = t + tStep;
}
return list;
}
private float calculateQuadSpline(float z0, float z1, float z2, float t) {
float a1 = (float) ((1.0 - t) * (1.0 - t) * z0);
float a2 = (float) (2.0 * t * (1 - t) * z1);
float a3 = (float) (t * t * z2);
float a4 = a1 + a2 + a3;
return a4;
}
public static void main(String[] args) {
launch(args);
}
}