Java 使用更新的路径()在场景中绘制新线
我是javafx的新手,用它来实现蚁群优化算法的一个版本。我写了一些代码,它应该显示一个小圆圈,作为蚂蚁在平面上随机移动。这很有效。但我无法修改代码以显示场景中蚂蚁的路径。基本上,当蚂蚁在二维平面上移动时,我希望蚂蚁的路径用线高亮显示 代码如下:Java 使用更新的路径()在场景中绘制新线,java,javafx,Java,Javafx,我是javafx的新手,用它来实现蚁群优化算法的一个版本。我写了一些代码,它应该显示一个小圆圈,作为蚂蚁在平面上随机移动。这很有效。但我无法修改代码以显示场景中蚂蚁的路径。基本上,当蚂蚁在二维平面上移动时,我希望蚂蚁的路径用线高亮显示 代码如下: import java.util.ArrayList; import java.util.Random; //Line can either be a sound or a shape import javafx.animation.Animat
import java.util.ArrayList;
import java.util.Random;
//Line can either be a sound or a shape
import javafx.animation.Animation.Status;
import javafx.animation.PathTransition;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.MoveTo;
import javafx.scene.shape.LineTo;
import javafx.scene.shape.Path;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
import javafx.util.Duration;
import java.lang.Object;
import javafx.scene.Node;
import javafx.scene.shape.Shape;
import javafx.scene.shape.Line;
public class TestMotion extends Application {
int N = 10;
static ArrayList<Integer> move = new ArrayList<Integer>();
private double sceneWidth = 512;
private double sceneHeight = 512;
MyNode node = new MyNode(0,0,5);
Path pathA = new Path();
int n = 10;
@Override
public void start(Stage primaryStage) throws Exception {
Group root = new Group();
root.getChildren().addAll(node, pathA);
Scene scene = new Scene( root, sceneWidth, sceneHeight);
primaryStage.setScene( scene);
primaryStage.show();
animate();
}
//convention conversion (i,j) to node number x
public static int convert(int i, int j, int N)
{
return (j*N +i+1);
}
//convention conversion node number x to (i,j)
//implement in order of definition
public static int reconvertY(int x, int N)
{
return (int) java.lang.Math.floor((x-1)/N);
}
public static int reconvertX(int x, int N, int j)
{
return (x-j*N-1);
}
private void animate() {
nextPos(move, N);
int y1 = reconvertY(move.get(move.size()-1), N);
int x1 = reconvertX(move.get(move.size()-1), N, y1);
MyNode here = new MyNode(10*x1, 10*y1, 1);
System.out.println(move.get(move.size()-1));
pathA.getElements().add (new MoveTo ( node.getTranslateX() + node.getBoundsInParent().getWidth() / 2.0, node.getTranslateY() + node.getBoundsInParent().getHeight() / 2.0));
pathA.getElements().add (new LineTo( here.getTranslateX() + here.getBoundsInParent().getWidth() / 2.0, here.getTranslateY() + here.getBoundsInParent().getHeight() / 2.0));
pathA.setStroke(Color.RED);
pathA.setStrokeWidth(1.0);
PathTransition pathTransitionA = new PathTransition();
pathTransitionA.setDuration(Duration.millis(1000));
pathTransitionA.setNode(node);
pathTransitionA.setPath(pathA);
pathTransitionA.play();
pathA = new Path();
pathTransitionA.setOnFinished( new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
if( pathTransitionA.getStatus() == Status.RUNNING)
{return;}
animate();
}
});
}
//allot new node to the arraylist such that it is adjacent to the previously assigned node
private void nextPos(ArrayList<Integer> array, int N)
{
//I removed this part to save space because it is probably irrelevant the the problem at hand
}
public static void main(String[] args) {
move.add(1);
launch(args);
}
public static class MyNode extends StackPane {
public MyNode(double x, double y, double r) {
// create circle
Circle circle = new Circle();
circle.setRadius(r);
circle.setFill(Color.BLUE);
// set position
setTranslateX( x);
setTranslateY( y);
getChildren().add(circle);
}
}
}
import java.util.ArrayList;
导入java.util.Random;
//线条可以是声音,也可以是形状
导入javafx.animation.animation.Status;
导入javafx.animation.PathTransition;
导入javafx.application.application;
导入javafx.event.ActionEvent;
导入javafx.event.EventHandler;
导入javafx.scene.Group;
导入javafx.scene.scene;
导入javafx.scene.control.Label;
导入javafx.scene.layout.StackPane;
导入javafx.scene.paint.Color;
导入javafx.scene.shape.MoveTo;
导入javafx.scene.shape.LineTo;
导入javafx.scene.shape.Path;
导入javafx.scene.shape.Circle;
导入javafx.stage.stage;
导入javafx.util.Duration;
导入java.lang.Object;
导入javafx.scene.Node;
导入javafx.scene.shape.shape;
导入javafx.scene.shape.Line;
公共类TestMotion扩展了应用程序{
int N=10;
静态ArrayList move=新建ArrayList();
专用双场景宽度=512;
专用双场景高=512;
MyNode=newmynode(0,0,5);
路径路径a=新路径();
int n=10;
@凌驾
public void start(Stage primaryStage)引发异常{
组根=新组();
root.getChildren().addAll(节点,路径);
场景=新场景(根、场景宽度、场景高度);
初级阶段。场景(场景);
primaryStage.show();
制作动画();
}
//将约定转换(i,j)为节点号x
公共静态整数转换(整数i,整数j,整数N)
{
返回(j*N+i+1);
}
//约定转换节点编号x到(i,j)
//按定义顺序实施
公共静态整数重置(整数x,整数N)
{
return(int)java.lang.Math.floor((x-1)/N);
}
公共静态整数再转换(整数x,整数N,整数j)
{
返回(x-j*N-1);
}
私有void动画(){
nextPos(移动,N);
int y1=重新转换(move.get(move.size()-1),N);
intx1=recovertx(move.get(move.size()-1),N,y1);
这里的MyNode=新的MyNode(10*x1,10*y1,1);
System.out.println(move.get(move.size()-1));
pathA.getElements().add(新移动到(node.getTranslateX()+node.getBoundsInParent().getWidth()/2.0,node.getTranslateY()+node.getBoundsInParent().getHeight()/2.0));
pathA.getElements().add(新的行到(here.getTranslateX()+here.getBoundsInParent().getWidth()/2.0,here.getTranslateY()+here.getBoundsInParent().getHeight()/2.0));
路径设定行程(颜色为红色);
路径设定行程宽度(1.0);
PathTransition pathTransitionA=新的PathTransition();
路径转换设置持续时间(持续时间毫秒(1000));
pathTransitionA.setNode(节点);
路径转换a.setPath(pathA);
路径转换a.play();
pathA=新路径();
pathTransitionA.setOnFinished(新的EventHandler(){
@凌驾
公共无效句柄(ActionEvent事件){
if(pathTransitionA.getStatus()==Status.RUNNING)
{return;}
制作动画();
}
});
}
//将新节点分配给arraylist,使其与先前分配的节点相邻
私有void nextPos(ArrayList数组,int N)
{
//为了节省空间,我删除了这个部分,因为它可能与当前的问题无关
}
公共静态void main(字符串[]args){
动议。加入(1);
发射(args);
}
公共静态类MyNode扩展StackPane{
公共MyNode(双x、双y、双r){
//创建圆
圆圈=新圆圈();
圆半径(r);
圆形。设置填充(颜色。蓝色);
//设定位置
setTranslateX(x);
setTranslateY(y);
getChildren().add(圆);
}
}
}
执行时,场景仅显示第一步的路径,然后完全停止显示路径。我不明白为什么。每次运行animate()
函数时,都会更新路径,并且节点
和此处
都应该定期更新。那么,每个迭代不应该显示蚂蚁的最新路径段吗
有人能解释一下这个问题吗?是否无法利用Path()
和PathTransition()
来显示这些段并避免使用Line()
你的方法没有错。唯一的问题是,无论何时调用animate()
,形成的路径的坐标都与以前一样。路径坐标始终返回以下值
1.0, 1.0 for moveTo and 5.0,5.0 for LineTo
每次路径变为新路径时,都需要传递新的坐标。另外,要在显示新路径的同时显示旧路径,您需要将新创建的路径
添加到组
以下是我在你的代码中所做的更改。看一看
import java.util.ArrayList;
import javafx.animation.Animation.Status;
import javafx.animation.PathTransition;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.MoveTo;
import javafx.scene.shape.LineTo;
import javafx.scene.shape.Path;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
import javafx.util.Duration;
public class TestMotion extends Application {
int N = 10;
static ArrayList<Integer> move = new ArrayList<Integer>();
private double sceneWidth = 512;
private double sceneHeight = 512;
MyNode node = new MyNode(0, 0, 5);
Group root; //Made root as global variable
int n = 10;
@Override
public void start(Stage primaryStage) throws Exception {
root = new Group();
root.getChildren().addAll(node);
Scene scene = new Scene(root, sceneWidth, sceneHeight);
primaryStage.setScene(scene);
primaryStage.show();
animate(0.0f, 0.0f, 5.0f, 5.0f); //Passing initial coordinates to the method
}
//convention conversion (i,j) to node number x
public static int convert(int i, int j, int N) {
return (j * N + i + 1);
}
//convention conversion node number x to (i,j)
//implement in order of definition
public static int reconvertY(int x, int N) {
return (int) java.lang.Math.floor((x - 1) / N);
}
public static int reconvertX(int x, int N, int j) {
return (x - j * N - 1);
}
private void animate(float moveX, float moveY, float lineX, float lineY) {
Path pathA = new Path();
root.getChildren().add(pathA);
nextPos(move, N);
int y1 = reconvertY(move.get(move.size() - 1), N);
int x1 = reconvertX(move.get(move.size() - 1), N, y1);
//Applying coordinates as obtained
pathA.getElements().add(new MoveTo(moveX, moveY));
pathA.getElements().add(new LineTo(lineX, lineY));
pathA.setStroke(Color.RED);
pathA.setStrokeWidth(1.0);
PathTransition pathTransitionA = new PathTransition();
pathTransitionA.setDuration(Duration.millis(100));
pathTransitionA.setNode(node);
pathTransitionA.setPath(pathA);
pathTransitionA.play();
pathTransitionA.setOnFinished(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
if (pathTransitionA.getStatus() == Status.RUNNING) {
return;
}
animate(lineX, lineY, lineX + 2, lineY + 2); //previous path's endpoint makes the start point of the new Path
}
});
}
//allot new node to the arraylist such that it is adjacent to the previously assigned node
private void nextPos(ArrayList<Integer> array, int N) {
//I removed this part to save space because it is probably irrelevant the the problem at hand
}
public static void main(String[] args) {
move.add(1);
launch(args);
}
public static class MyNode extends StackPane {
public MyNode(double x, double y, double r) {
// create circle
Circle circle = new Circle();
circle.setRadius(r);
circle.setFill(Color.BLUE);
// set position
setTranslateX(x);
setTranslateY(y);
getChildren().add(circle);
}
}
}
import java.util.ArrayList;
导入javafx.animation.animation.Status;
导入javafx.animation.PathTransition;
导入javafx.application.application;
导入javafx.event.ActionEvent;
导入javafx.event.EventHandler;
导入javafx.scene.Group;
导入javafx.scene.scene;
导入javafx.scene.layout.StackPane;
导入javafx.scene.paint.Color;
导入javafx.scene.shape.MoveTo;
导入javafx.scene.shape.LineTo;
导入javafx.scene.shape.Path;
导入javafx.scene.shape.Circle;
导入javafx.stage.stage;
导入javafx.util.Duration;
公共类TestMotion扩展了应用程序{
int N=10;
静态A