diff --git a/.classpath b/.classpath
new file mode 100644
index 0000000..1ba2e07
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.project b/.project
new file mode 100644
index 0000000..2cc75e8
--- /dev/null
+++ b/.project
@@ -0,0 +1,34 @@
+
+
+ PhysicalRealTimeRouteFinder
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+ org.eclipse.m2e.core.maven2Nature
+
+
+
+ 1677335971077
+
+ 30
+
+ org.eclipse.core.resources.regexFilterMatcher
+ node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__
+
+
+
+
diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..654c175
--- /dev/null
+++ b/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,3 @@
+eclipse.preferences.version=1
+encoding//src/main/java=UTF-8
+encoding/=UTF-8
diff --git a/.settings/org.eclipse.jdt.apt.core.prefs b/.settings/org.eclipse.jdt.apt.core.prefs
new file mode 100644
index 0000000..ec0c557
--- /dev/null
+++ b/.settings/org.eclipse.jdt.apt.core.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.apt.aptEnabled=false
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..391de62
--- /dev/null
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,9 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
+org.eclipse.jdt.core.compiler.processAnnotations=disabled
+org.eclipse.jdt.core.compiler.release=disabled
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000..14b697b
--- /dev/null
+++ b/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..3be99a1
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,5 @@
+{
+ "java.format.onType.enabled": false,
+ "java.format.settings.url": "D:\\dformat.xml",
+ "maven.view": "flat"
+}
\ No newline at end of file
diff --git a/demo.json b/demo.json
new file mode 100644
index 0000000..ec35118
--- /dev/null
+++ b/demo.json
@@ -0,0 +1,21 @@
+坐标系:z轴朝上
+{
+ "DataType":"Map",//数据种类 Map地图数据
+ "Map":[[0,1,2,1],[2,2,3,1]]
+ //地图数据,数组内每个元素为一个block,[double x,double y,double z,int type] type参数为方块类型,目前只有1为实体方块
+}
+
+{
+ "DataType":"Frame",//数据种类 Frame计算数据帧
+ "Info":{
+ "FrameNumber":0,//帧编号 int
+ "RunTime":123456,//程序运算总时间 long
+ "FrameCalculateTime":12345,//帧计算时间 long
+ },
+ "Route":[[1,2,3],[3,4,5]],//路径标记(可以用特效也可以半透明方块)同地图数据,[double x,double y,double z]
+ "Entity":{
+ "Position":[0,1,1],//实体方块位置(立方体底面中心为坐标原点) [double x,double y,double z]
+ "BoundingBox":[1,1,1],//碰撞箱大小(立方体大小) [double x,double y,double z]
+ "Rotation":[30,30]//[double pitch,double yaw] pitch为与z轴正方向的夹角(0-180),yaw为与x轴正方向夹角(0-360)卦限顺序
+ }
+}
\ No newline at end of file
diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml
new file mode 100644
index 0000000..0fc1e7b
--- /dev/null
+++ b/dependency-reduced-pom.xml
@@ -0,0 +1,43 @@
+
+
+ 4.0.0
+ cn.dxp
+ PhysicalRealTimeRouteFinder
+ PhysicalRealTimeRouteFinder
+ 1.0-SNAPSHOT
+ http://maven.apache.org
+
+
+
+ maven-shade-plugin
+ 3.2.4
+
+
+ package
+
+ shade
+
+
+
+
+ cn.dxp.PRTRF
+
+
+
+
+
+
+
+
+
+
+ junit
+ junit
+ 3.8.1
+ test
+
+
+
+ UTF-8
+
+
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..0a17a4c
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,56 @@
+
+ 4.0.0
+ cn.dxp
+ PhysicalRealTimeRouteFinder
+ jar
+ 1.0-SNAPSHOT
+ PhysicalRealTimeRouteFinder
+ http://maven.apache.org
+
+
+ junit
+ junit
+ 3.8.1
+ test
+
+
+ org.json
+ json
+ 20210307
+
+
+ org.apache.httpcomponents
+ httpclient
+ 4.5.13
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 3.2.4
+
+
+ package
+
+ shade
+
+
+
+
+ cn.dxp.PRTRF
+
+
+
+
+
+
+
+
+
+
+ UTF-8
+
+
diff --git a/run.bat b/run.bat
new file mode 100644
index 0000000..ffe1cdd
--- /dev/null
+++ b/run.bat
@@ -0,0 +1,5 @@
+@echo off
+call mvn package
+pause
+call java -Dfile.encoding=utf-8 -jar ./target/PhysicalRealTimeRouteFinder-1.0-SNAPSHOT.jar
+pause
\ No newline at end of file
diff --git a/src/main/java/cn/dxp/PRTRF.java b/src/main/java/cn/dxp/PRTRF.java
new file mode 100644
index 0000000..8b566d2
--- /dev/null
+++ b/src/main/java/cn/dxp/PRTRF.java
@@ -0,0 +1,42 @@
+package cn.dxp;
+
+import cn.dxp.math.*;
+
+public class PRTRF{
+ static final String version = "v1.0";
+ static final int threadCount = 8;
+
+ public static void main(String[] args){
+ System.out.println("PhysicalRealTimeRouteFinder " + version);
+ PhysicalRealTimeRouteFinder p = new PhysicalRealTimeRouteFinder();
+ p.resetHttpSender();
+ try{
+ System.out.println("绘制地图中...");
+ p.generateMap(500, 50, 500);
+ while(true){
+ if(p.hasMap()){
+ System.out.println("地图数据绘制完成");
+ break;
+ }
+ Thread.sleep(200);
+ }
+ System.out.println("生成地图耗时:" + p.mapGenerator.usedTime + "ms");
+ System.out.println("发送地图数据");
+ p.httpSender.addData(p.encodeMapJsonData());
+ System.out.println("计算路线帧...线程数:" + threadCount);
+ Entity e = new Entity(p.mapGenerator.startPoint);
+ e.setBoundingBox(new Vector3(1, 1, 1));
+ p.setEntity(e);
+ p.findRoute(p.getMap(), p.mapGenerator.startPoint, p.mapGenerator.endPoint, 8);
+ while(true){
+ if(p.hasNewFrame()){
+ System.out.println("发送帧 " + p.currentFrame);
+ p.httpSender.addData(p.encodeFrameJsonData());
+ }
+ Thread.sleep(1);
+ }
+ }catch (Exception e){
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/src/main/java/cn/dxp/PhysicalRealTimeRouteFinder.java b/src/main/java/cn/dxp/PhysicalRealTimeRouteFinder.java
new file mode 100644
index 0000000..604e90a
--- /dev/null
+++ b/src/main/java/cn/dxp/PhysicalRealTimeRouteFinder.java
@@ -0,0 +1,151 @@
+package cn.dxp;
+
+import cn.dxp.map.*;
+import cn.dxp.math.*;
+import cn.dxp.network.*;
+import cn.dxp.route.*;
+import java.util.*;
+import org.json.JSONArray;
+import org.json.JSONObject;
+
+public class PhysicalRealTimeRouteFinder{
+
+ public HttpSender httpSender;
+ public MapGenerator mapGenerator;
+ public RouteFinder routeFinder;
+ public Entity entity = new Entity(0, 0, 0);
+ public ArrayList> frameQueue = new ArrayList>();
+ public int currentFrame = 0;
+ public long startTime = System.currentTimeMillis();
+
+ public PhysicalRealTimeRouteFinder(){
+
+ }
+
+ public void generateMap(double x, double y, double z){
+ this.mapGenerator = new MapGenerator(this, x, y, z);
+ this.mapGenerator.start();
+ }
+
+ public boolean hasMap(){
+ if(this.mapGenerator != null){
+ if(this.mapGenerator.isSuccess()){
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public HashMap getMap(){
+ if(this.hasMap()){
+ return this.mapGenerator.mapData;
+ }
+ return new HashMap();
+ }
+
+ public void findRoute(HashMap map, Vector3 startPoint, Vector3 endPoint,
+ int threadCount){
+ this.routeFinder = new AdvancedRouteFinder(this, map, this.entity, threadCount);
+ this.routeFinder.setStart(startPoint);
+ this.routeFinder.setDestination(endPoint);
+ this.routeFinder.taskSearch();
+ }
+
+ public void setEntity(Entity e){
+ this.entity = e;
+ }
+
+ public boolean hasNewFrame(){
+ if(this.frameQueue.size() > 0){
+ return true;
+ }
+ return false;
+ }
+
+ public HashMap getNewFrame(){
+ return this.frameQueue.get(0);
+ }
+
+ public boolean deleteNewFrame(){
+ this.frameQueue.remove(0);
+ return true;
+ }
+
+ public void addNewFrame(HashMap f){
+ this.frameQueue.add(f);
+ }
+
+ public void resetHttpSender(){
+ if(this.httpSender == null){
+ this.httpSender = new HttpSender(this);
+ }else{
+ HttpSender old = this.httpSender;
+ this.httpSender = new HttpSender(this);
+ this.httpSender.dataQueue = old.dataQueue;
+ }
+ this.httpSender.start();
+ }
+
+ public String encodeMapJsonData(){
+ JSONObject jsonData = new JSONObject();
+ HashMap mdata = this.mapGenerator.mapData;
+ JSONArray map = new JSONArray();
+ int mapindex = 0;
+ Iterator it = (Iterator) mdata.keySet().iterator();
+ while(it.hasNext()){
+ Vector3 pos = (Vector3) it.next();
+ JSONArray point = new JSONArray();
+ point.put(0, pos.x);
+ point.put(1, pos.y);
+ point.put(2, pos.z);
+ point.put(3, mdata.get(pos));
+ map.put(mapindex, point);
+ mapindex++;
+ }
+ jsonData.put("DataType", "Map");
+ jsonData.put("Map", map);
+ return jsonData.toString();
+ }
+
+ @SuppressWarnings("unchecked")
+ public String encodeFrameJsonData(){
+ HashMap fdata = this.getNewFrame();
+ if(fdata == null){
+ return "";
+ }
+ ArrayList rdata = (ArrayList) fdata.get("Route");
+ JSONObject jsonData = new JSONObject();
+ JSONObject en = new JSONObject();
+ JSONArray route = new JSONArray();
+ JSONObject info = new JSONObject();
+ for(int i = 0; i < rdata.size(); i++){
+ Vector3 pos = rdata.get(i);
+ JSONArray point = new JSONArray();
+ point.put(0, pos.x);
+ point.put(1, pos.y);
+ point.put(2, pos.z);
+ route.put(i, point);
+ }
+ HashMap idata = (HashMap) fdata.get("Info");
+ Iterator it = (Iterator) idata.keySet().iterator();
+ while(it.hasNext()){
+ String k = (String) it.next();
+ info.put(k, idata.get(k));
+ }
+ info.put("RunTime", System.currentTimeMillis() - this.startTime);
+ info.put("FrameNumber", this.currentFrame);
+ en.put("Position",
+ new JSONArray().put(0, this.entity.x).put(1, this.entity.y).put(2, this.entity.z));
+ en.put("BoundingBox", new JSONArray().put(0, this.entity.getBoundingBox().x)
+ .put(1, this.entity.getBoundingBox().y).put(2, this.entity.getBoundingBox().z));
+ en.put("Rotation", new JSONArray().put(0, this.entity.pitch).put(1, this.entity.yaw));
+ jsonData.put("DataType", "Frame");
+ jsonData.put("Route", route);
+ jsonData.put("Info", info);
+ jsonData.put("Entity", en);
+ System.out.println(this.currentFrame+"帧已打包,耗时"+String.valueOf(idata.get("FrameCalculateTime")));
+ this.currentFrame++;
+ this.deleteNewFrame();
+ return jsonData.toString();
+ }
+}
diff --git a/src/main/java/cn/dxp/map/MapGenerator.java b/src/main/java/cn/dxp/map/MapGenerator.java
new file mode 100644
index 0000000..83acdb2
--- /dev/null
+++ b/src/main/java/cn/dxp/map/MapGenerator.java
@@ -0,0 +1,137 @@
+package cn.dxp.map;
+
+import java.util.*;
+
+import cn.dxp.math.*;
+import cn.dxp.*;
+
+public class MapGenerator extends Thread{
+
+ public PhysicalRealTimeRouteFinder p;
+ public HashMap mapData = new HashMap();
+ public Vector3 startPoint;
+ public Vector3 endPoint;
+ private boolean success = false;
+ private Vector3 size;
+ private long startTime;
+ public long usedTime;
+
+ public MapGenerator(PhysicalRealTimeRouteFinder prtrf, double x, double y, double z){
+ this.p = prtrf;
+ this.size = new Vector3(x, y, z);
+ }
+
+ // 0 air
+ // 1 stone
+ // 2 water
+ // 3
+
+ @Override
+ public void run(){
+ startTime = System.currentTimeMillis();
+ this.mapData.putAll(generateLand(this.size));
+ this.mapData = addAir(this.mapData, this.size);
+ this.spawnPos();
+ this.success = true;
+ usedTime = System.currentTimeMillis() - startTime;
+ }
+
+ public void spawnPos(){
+ for(int i = (int) size.y; i >= 0; i--){
+ if(this.mapData.containsKey(new Vector3(0, i, 0))){
+ if(this.mapData.get(new Vector3(0, i, 0)) == 1){
+ if(i == (int) size.z){
+ this.mapData.put(new Vector3(0, i - 1, 0), 1);
+ this.mapData.remove(new Vector3(0, i, 0));
+ i--;
+ }else{
+ this.startPoint = new Vector3(0, i + 1, 0);
+ break;
+ }
+ }
+ }
+ }
+ for(int i = (int) size.y; i >= 0; i--){
+ if(this.mapData.containsKey(new Vector3(size.x - 1, i, size.z - 1))){
+ if(this.mapData.get(new Vector3(size.x - 1, i, size.z - 1)) == 1){
+ if(i == (int) size.z){
+ this.mapData.put(new Vector3(size.x - 1, i - 1, size.z - 1), 1);
+ this.mapData.remove(new Vector3(size.x - 1, i, size.z - 1));
+ i--;
+ }else{
+ this.endPoint = new Vector3(size.x - 1, i + 1, size.z - 1);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ public static HashMap generateLand(double x, double y, double z){
+ return generateLand(new Vector3(x, y, z));
+ }
+
+ public static HashMap generateLand(Vector3 landSize){
+ HashMap mapDataCache = new HashMap();
+ double h = 6;
+ if(landSize.z < 2){
+ h = 1;
+ }
+ for(double x = -2; x < landSize.x + 2; x++){
+ for(double z = -2; z < landSize.z + 2; z++){
+ mapDataCache.put(new Vector3(x, -1, z), 1);
+ }
+
+ }
+ for(double x = 0; x < landSize.x; x++){
+ for(double y = 0; y < h; y++){
+ for(double z = 0; z < landSize.z; z++){
+ mapDataCache.put(new Vector3(x, y, z), 1);
+ }
+ }
+ }
+ return mapDataCache;
+ }
+
+ public static HashMap generateObstacle(double x, double y, double z){
+ return generateObstacle(new Vector3(x, y, z));
+ }
+
+ public static HashMap generateObstacle(Vector3 landSize){
+ HashMap mapDataCache = new HashMap();
+
+ for(double x = 0; x < landSize.x; x++){
+ for(double z = 0; z < landSize.z; z++){
+ if(Math.random() <= 0.2){
+ int h = 0;
+ if(Math.random() <= 0.6){
+ h = 1;
+ }else{
+ h = 2;
+ }
+ for(double y = 6; y < 6 + h; y++){
+ mapDataCache.put(new Vector3(x, y, z), 1);
+ }
+ }
+ }
+ }
+ return mapDataCache;
+ }
+
+ public static HashMap addAir(HashMap map, Vector3 landSize){
+ for(double x = -1; x < landSize.x; x++){
+ for(double y = -1; y <= landSize.y + 1; y++){
+ for(double z = -1; z < landSize.z; z++){
+ if(!map.containsKey(new Vector3(x, y, z))){
+ map.put(new Vector3(x, y, z), 0);
+ }
+ }
+ }
+ }
+ return map;
+ }
+
+ public boolean isSuccess(){
+ return(this.success && this.mapData.size() > 0);
+ }
+}
diff --git a/src/main/java/cn/dxp/math/Entity.java b/src/main/java/cn/dxp/math/Entity.java
new file mode 100644
index 0000000..1d485be
--- /dev/null
+++ b/src/main/java/cn/dxp/math/Entity.java
@@ -0,0 +1,30 @@
+package cn.dxp.math;
+
+public class Entity extends Vector3{
+
+ private Vector3 bb;
+ public double pitch;
+ public double yaw;
+
+ public Entity(Vector3 vec){
+ this(vec.x, vec.y, vec.z);
+ }
+
+ public Entity(double x, double y, double z){
+ this(x, y, z, 0, 0);
+ }
+
+ public Entity(double x, double y, double z, double pi, double ya){
+ super(x, y, z);
+ this.pitch = pi;
+ this.pitch = pi;
+ }
+
+ public Vector3 getBoundingBox(){
+ return bb;
+ }
+
+ public void setBoundingBox(Vector3 b){
+ this.bb=b;
+ }
+}
diff --git a/src/main/java/cn/dxp/math/Vector3.java b/src/main/java/cn/dxp/math/Vector3.java
new file mode 100644
index 0000000..8de86a4
--- /dev/null
+++ b/src/main/java/cn/dxp/math/Vector3.java
@@ -0,0 +1,280 @@
+package cn.dxp.math;
+
+public class Vector3 implements Cloneable{
+
+ public double x;
+ public double y;
+ public double z;
+
+ public Vector3(){
+ this(0, 0, 0);
+ }
+
+ public Vector3(double x){
+ this(x, 0, 0);
+ }
+
+ public Vector3(double x, double y){
+ this(x, y, 0);
+ }
+
+ public Vector3(double x, double y, double z){
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ }
+
+ public double getX(){
+ return this.x;
+ }
+
+ public double getY(){
+ return this.y;
+ }
+
+ public double getZ(){
+ return this.z;
+ }
+
+ public int getFloorX(){
+ return (int) Math.floor(this.x);
+ }
+
+ public int getFloorY(){
+ return (int) Math.floor(this.y);
+ }
+
+ public int getFloorZ(){
+ return (int) Math.floor(this.z);
+ }
+
+ public double getRight(){
+ return this.x;
+ }
+
+ public double getUp(){
+ return this.y;
+ }
+
+ public double getForward(){
+ return this.z;
+ }
+
+ public double getSouth(){
+ return this.x;
+ }
+
+ public double getWest(){
+ return this.z;
+ }
+
+ public Vector3 add(double x){
+ return this.add(x, 0, 0);
+ }
+
+ public Vector3 add(double x, double y){
+ return this.add(x, y, 0);
+ }
+
+ public Vector3 add(double x, double y, double z){
+ return new Vector3(this.x + x, this.y + y, this.z + z);
+ }
+
+ public Vector3 add(Vector3 x){
+ return new Vector3(this.x + x.getX(), this.y + x.getY(), this.z + x.getZ());
+ }
+
+ public Vector3 subtract(){
+ return this.subtract(0, 0, 0);
+ }
+
+ public Vector3 subtract(double x){
+ return this.subtract(x, 0, 0);
+ }
+
+ public Vector3 subtract(double x, double y){
+ return this.subtract(x, y, 0);
+ }
+
+ public Vector3 subtract(double x, double y, double z){
+ return this.add(-x, -y, -z);
+ }
+
+ public Vector3 subtract(Vector3 x){
+ return this.add(-x.getX(), -x.getY(), -x.getZ());
+ }
+
+ public Vector3 multiply(double number){
+ return new Vector3(this.x * number, this.y * number, this.z * number);
+ }
+
+ public Vector3 divide(double number){
+ return new Vector3(this.x / number, this.y / number, this.z / number);
+ }
+
+ public Vector3 ceil(){
+ return new Vector3((int) Math.ceil(this.x), (int) Math.ceil(this.y),
+ (int) Math.ceil(this.z));
+ }
+
+ public Vector3 floor(){
+ return new Vector3(this.getFloorX(), this.getFloorY(), this.getFloorZ());
+ }
+
+ public Vector3 round(){
+ return new Vector3(Math.round(this.x), Math.round(this.y), Math.round(this.z));
+ }
+
+ public Vector3 abs(){
+ return new Vector3((int) Math.abs(this.x), (int) Math.abs(this.y), (int) Math.abs(this.z));
+ }
+
+ public double distance(Vector3 pos){
+ return Math.sqrt(this.distanceSquared(pos));
+ }
+
+ public double distanceSquared(Vector3 pos){
+ return Math.pow(this.x - pos.x, 2) + Math.pow(this.y - pos.y, 2)
+ + Math.pow(this.z - pos.z, 2);
+ }
+
+ public double length(){
+ return Math.sqrt(this.lengthSquared());
+ }
+
+ public double lengthSquared(){
+ return this.x * this.x + this.y * this.y + this.z * this.z;
+ }
+
+ public Vector3 normalize(){
+ double len = this.lengthSquared();
+ if(len > 0){
+ return this.divide(Math.sqrt(len));
+ }
+ return new Vector3(0, 0, 0);
+ }
+
+ public double dot(Vector3 v){
+ return this.x * v.x + this.y * v.y + this.z * v.z;
+ }
+
+ public Vector3 cross(Vector3 v){
+ return new Vector3(this.y * v.z - this.z * v.y, this.z * v.x - this.x * v.z,
+ this.x * v.y - this.y * v.x);
+ }
+
+ /**
+ * Returns a new vector with x value equal to the second parameter, along the line between this
+ * vector and the passed in vector, or null if not possible.
+ *
+ * @param v vector
+ * @param x x value
+ * @return intermediate vector
+ */
+ public Vector3 getIntermediateWithXValue(Vector3 v, double x){
+ double xDiff = v.x - this.x;
+ double yDiff = v.y - this.y;
+ double zDiff = v.z - this.z;
+ if(xDiff * xDiff < 0.0000001){
+ return null;
+ }
+ double f = (x - this.x) / xDiff;
+ if(f < 0 || f > 1){
+ return null;
+ }else{
+ return new Vector3(this.x + xDiff * f, this.y + yDiff * f, this.z + zDiff * f);
+ }
+ }
+
+ /**
+ * Returns a new vector with y value equal to the second parameter, along the line between this
+ * vector and the passed in vector, or null if not possible.
+ *
+ * @param v vector
+ * @param y y value
+ * @return intermediate vector
+ */
+ public Vector3 getIntermediateWithYValue(Vector3 v, double y){
+ double xDiff = v.x - this.x;
+ double yDiff = v.y - this.y;
+ double zDiff = v.z - this.z;
+ if(yDiff * yDiff < 0.0000001){
+ return null;
+ }
+ double f = (y - this.y) / yDiff;
+ if(f < 0 || f > 1){
+ return null;
+ }else{
+ return new Vector3(this.x + xDiff * f, this.y + yDiff * f, this.z + zDiff * f);
+ }
+ }
+
+ /**
+ * Returns a new vector with z value equal to the second parameter, along the line between this
+ * vector and the passed in vector, or null if not possible.
+ *
+ * @param v vector
+ * @param z z value
+ * @return intermediate vector
+ */
+ public Vector3 getIntermediateWithZValue(Vector3 v, double z){
+ double xDiff = v.x - this.x;
+ double yDiff = v.y - this.y;
+ double zDiff = v.z - this.z;
+ if(zDiff * zDiff < 0.0000001){
+ return null;
+ }
+ double f = (z - this.z) / zDiff;
+ if(f < 0 || f > 1){
+ return null;
+ }else{
+ return new Vector3(this.x + xDiff * f, this.y + yDiff * f, this.z + zDiff * f);
+ }
+ }
+
+ public Vector3 setComponents(double x, double y, double z){
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ return this;
+ }
+
+ @Override
+ public String toString(){
+ return "Vector3(x=" + this.x + ",y=" + this.y + ",z=" + this.z + ")";
+ }
+
+ @Override
+ public boolean equals(Object obj){
+ if(!(obj instanceof Vector3)){
+ return false;
+ }
+
+ Vector3 other = (Vector3) obj;
+
+ return this.x == other.x && this.y == other.y && this.z == other.z;
+ }
+
+ @Override
+ public int hashCode(){
+ return ((int) x ^ ((int) z << 12)) ^ ((int) y << 24);
+ }
+
+ public int rawHashCode(){
+ return super.hashCode();
+ }
+
+ @Override
+ public Vector3 clone(){
+ try{
+ return (Vector3) super.clone();
+ }catch (CloneNotSupportedException e){
+ return null;
+ }
+ }
+
+ public Vector3 random(){
+ return new Vector3(this.x * Math.random(), this.getFloorY() * Math.random(),
+ this.getFloorZ() * Math.random());
+ }
+}
diff --git a/src/main/java/cn/dxp/network/HttpSender.java b/src/main/java/cn/dxp/network/HttpSender.java
new file mode 100644
index 0000000..f59f01d
--- /dev/null
+++ b/src/main/java/cn/dxp/network/HttpSender.java
@@ -0,0 +1,182 @@
+package cn.dxp.network;
+
+import java.util.*;
+import java.util.Map.Entry;
+import java.io.*;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.util.EntityUtils;
+
+import cn.dxp.*;
+
+public class HttpSender extends Thread{
+ static final String serverip = "http://10.100.233.123:8080";
+
+ public PhysicalRealTimeRouteFinder p;
+ public ArrayList> dataQueue = new ArrayList>();
+
+ public HttpSender(PhysicalRealTimeRouteFinder prtrf){
+ this.p = prtrf;
+ }
+
+ @Override
+ public void run(){
+ while(true){
+ try{
+ //sleep(500);
+ if(this.dataQueue.size() != 0){
+ System.out.println(doPost(this.dataQueue.get(0)));
+ this.dataQueue.remove(0);
+ }else{
+ sleep(500);
+ }
+ }catch (InterruptedException e){
+ e.getStackTrace();
+ this.p.resetHttpSender();
+ }
+ }
+ }
+
+ public void addData(final String s){
+ if(s.isEmpty()){
+ return;
+ }
+ this.dataQueue.add(new HashMap(){
+ {
+ put("json", s);
+ }
+ });
+ }
+
+ public void addData(HashMap d){
+ this.dataQueue.add(d);
+ }
+
+ public static String doGet(){
+ String url = serverip;
+ CloseableHttpClient httpClient = null;
+ CloseableHttpResponse response = null;
+ String result = "";
+ try{
+ // 通过址默认配置创建一个httpClient实例
+ httpClient = HttpClients.createDefault();
+ // 创建httpGet远程连接实例
+ HttpGet httpGet = new HttpGet(url);
+ // 设置请求头信息,鉴权
+ httpGet.setHeader("Authorization", "Bearer da3efcbf-0845-4fe3-8aba-ee040be542c0");
+ // 设置配置请求参数
+ RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000)// 连接主机服务超时时间
+ .setConnectionRequestTimeout(35000)// 请求超时时间
+ .setSocketTimeout(60000)// 数据读取超时时间
+ .build();
+ // 为httpGet实例设置配置
+ httpGet.setConfig(requestConfig);
+ // 执行get请求得到返回对象
+ response = httpClient.execute(httpGet);
+ // 通过返回对象获取返回数据
+ HttpEntity entity = response.getEntity();
+ // 通过EntityUtils中的toString方法将结果转换为字符串
+ result = EntityUtils.toString(entity);
+ }catch (ClientProtocolException e){
+ e.printStackTrace();
+ }catch (IOException e){
+ e.printStackTrace();
+ }
+ finally{
+ // 关闭资源
+ if(null != response){
+ try{
+ response.close();
+ }catch (IOException e){
+ e.printStackTrace();
+ }
+ }
+ if(null != httpClient){
+ try{
+ httpClient.close();
+ }catch (IOException e){
+ e.printStackTrace();
+ }
+ }
+ }
+ return result;
+ }
+
+ public static String doPost(Map paramMap){
+ String url = serverip;
+ CloseableHttpClient httpClient = null;
+ CloseableHttpResponse httpResponse = null;
+ String result = "";
+ // 创建httpClient实例
+ httpClient = HttpClients.createDefault();
+ // 创建httpPost远程连接实例
+ HttpPost httpPost = new HttpPost(url);
+ // 配置请求参数实例
+ RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000)// 设置连接主机服务超时时间
+ .setConnectionRequestTimeout(35000)// 设置连接请求超时时间
+ .setSocketTimeout(60000)// 设置读取数据连接超时时间
+ .build();
+ // 为httpPost实例设置配置
+ httpPost.setConfig(requestConfig);
+ // 设置请求头
+ httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded");
+ // 封装post请求参数
+ if(null != paramMap && paramMap.size() > 0){
+ List nvps = new ArrayList();
+ // 通过map集成entrySet方法获取entity
+ Set> entrySet = paramMap.entrySet();
+ // 循环遍历,获取迭代器
+ Iterator> iterator = entrySet.iterator();
+ while(iterator.hasNext()){
+ Entry mapEntry = iterator.next();
+ nvps.add(new BasicNameValuePair(mapEntry.getKey(), mapEntry.getValue().toString()));
+ }
+
+ // 为httpPost设置封装好的请求参数
+ try{
+ httpPost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));
+ }catch (UnsupportedEncodingException e){
+ e.printStackTrace();
+ }
+ }
+ try{
+ // httpClient对象执行post请求,并返回响应参数对象
+ httpResponse = httpClient.execute(httpPost);
+ // 从响应对象中获取响应内容
+ HttpEntity entity = httpResponse.getEntity();
+ result = EntityUtils.toString(entity);
+ }catch (ClientProtocolException e){
+ e.printStackTrace();
+ }catch (IOException e){
+ e.printStackTrace();
+ }
+ finally{
+ // 关闭资源
+ if(null != httpResponse){
+ try{
+ httpResponse.close();
+ }catch (IOException e){
+ e.printStackTrace();
+ }
+ }
+ if(null != httpClient){
+ try{
+ httpClient.close();
+ }catch (IOException e){
+ e.printStackTrace();
+ }
+ }
+ }
+ return result;
+ }
+}
diff --git a/src/main/java/cn/dxp/route/AdvancedRouteFinder.java b/src/main/java/cn/dxp/route/AdvancedRouteFinder.java
new file mode 100644
index 0000000..edb0333
--- /dev/null
+++ b/src/main/java/cn/dxp/route/AdvancedRouteFinder.java
@@ -0,0 +1,298 @@
+package cn.dxp.route;
+
+import cn.dxp.*;
+import cn.dxp.math.*;
+
+import java.util.*;
+
+public class AdvancedRouteFinder extends RouteFinder{
+ private boolean succeed = false, searching = false;
+ //private Vector3 realDestination = null;
+ private HashSet open = new HashSet();
+ private Grid grid = new Grid();
+ public int heightLimit = 1;
+
+
+ public AdvancedRouteFinder(PhysicalRealTimeRouteFinder prtrf, HashMap m,
+ Entity entity, int threadCount){
+ super(prtrf, m, entity, threadCount);
+ }
+
+ @Override
+ public boolean search(){
+ this.startTime = System.currentTimeMillis();
+ this.stopRouteFindUntil = System.currentTimeMillis() + 10000;
+ this.succeed = false;
+ this.searching = true;
+ this.resetNodes();
+ this.grid.clear();
+ open = new HashSet();
+
+ if(this.getStart() == null || this.getDestination() == null){
+ return this.succeed = this.searching = false;
+ }
+ Vector3 r = this.getWalkablePosition((Vector3) this.getDestination()).floor();
+ /*if(r.equals(new Vector3(-1, -100, -1)) || r.equals(new Vector3(-1, -101, -1))){
+ return this.succeed = this.searching = false;
+ }*/
+
+ Node start = new Node(this.getStart().floor());
+ Node endNode = new Node(r);
+ try{
+ start.f = start.g = 0;
+ open.add(start);
+ this.grid.putNode(start);
+ this.grid.putNode(endNode);
+ }catch (Exception e){
+ return this.succeed = this.searching = false;
+ }
+
+ int limit = 100000;
+ while(!open.isEmpty() && limit-- > 0){
+ if(this.forceStop){
+ this.resetNodes();
+ this.forceStop = false;
+ return this.succeed = this.searching = false;
+ }
+ Node node = null;
+
+ double f = Double.MAX_VALUE;
+ try{
+ for(Node cur: this.open){
+ if(cur.f < f && cur.f != -1){
+ node = cur;
+ f = cur.f;
+ }
+ }
+ }catch (Exception e){
+ this.searching = false;
+ this.succeed = true;
+ nodes.add(new Node(this.getDestination()));
+ return true;
+ }
+
+ if(node == null){
+ this.searching = false;
+ this.succeed = true;
+ nodes.add(new Node(this.getDestination()));
+ return true;
+ }
+
+ if(endNode.equals(node)){
+ ArrayList nodes = new ArrayList();
+ nodes.add(node);
+ //Node last = node;
+ while((node = node.getParent()) != null){
+ nodes.add(new Node(node.getVector3().add(0.5, 0, 0.5)));
+ if(this.forceStop){
+ this.resetNodes();
+ this.forceStop = false;
+ return this.succeed = this.searching = false;
+ }
+ }
+ nodes.remove(nodes.size() - 1);
+ Collections.reverse(nodes);
+
+
+ this.addNodes(nodes);
+
+ this.succeed = true;
+ this.searching = false;
+ return true;
+ }
+ node.closed = true;
+ open.remove(node);
+
+ for(Node neighbor: this.getNeighbors(node)){
+ if(neighbor.closed)
+ continue;
+
+ double tentative_gScore = node.g + 1;
+
+ if(!open.contains(neighbor))
+ open.add(neighbor);
+ else if(neighbor.g != -1 && tentative_gScore >= neighbor.g)
+ continue;
+
+ neighbor.setParent(node);
+ neighbor.g = tentative_gScore;
+ neighbor.f = neighbor.g + neighbor.getVector3().distance(endNode.getVector3());
+
+ if(this.forceStop){
+ this.resetNodes();
+ this.forceStop = false;
+ return this.succeed = this.searching = false;
+ }
+ }
+ }
+
+ if(!this.succeed){
+ this.searching = false;
+ this.succeed = true;
+ nodes.add(new Node(this.getDestination()));
+ }
+ return this.succeed;
+ }
+
+ public Set getNeighbors(Node node){
+ HashSet neighbors = new HashSet();
+ Vector3 vec = node.getVector3();
+ boolean bb = false;
+ boolean b1 = false;
+ boolean b2 = false;
+ boolean b3 = false;
+ boolean b4 = false;
+ Vector3 vec1 = this.getWalkablePosition(vec.add(1, 0, 0));
+ Vector3 vec2 = this.getWalkablePosition(vec.add(0, 0, 1));
+ Vector3 vec3 = this.getWalkablePosition(vec.add(-1, 0, 0));
+ Vector3 vec4 = this.getWalkablePosition(vec.add(0, 0, -1));
+ Vector3 vec5;
+ Vector3 vec6;
+ Vector3 vec7;
+ Vector3 vec8;
+ Vector3 a = new Vector3(-1, -1, -1);
+ Vector3 b = new Vector3(-1, -2, -1);
+ int bt = map.get(vec.add(0, 2, 0));
+ if(bt == 0){
+ bb = true;
+ }
+
+ if(!vec1.equals(b)){
+ if(vec1.y <= vec.y){
+ b1 = true;
+ }
+ if(!vec1.equals(a) && bb){
+ neighbors.add(this.grid.getNode(vec1));
+ }
+ }
+ if(!vec2.equals(b)){
+ if(vec2.y <= vec.y){
+ b2 = true;
+ }
+ if(!vec2.equals(a) && bb){
+ neighbors.add(this.grid.getNode(vec2));
+ }
+ }
+ if(!vec3.equals(b)){
+ if(vec3.y <= vec.y){
+ b3 = true;
+ }
+ if(!vec3.equals(a) && bb){
+ neighbors.add(this.grid.getNode(vec3));
+ }
+ }
+ if(!vec4.equals(b)){
+ if(vec4.y <= vec.y){
+ b4 = true;
+ }
+ if(!vec4.equals(a) && bb){
+ neighbors.add(this.grid.getNode(vec4));
+ }
+ }
+
+ if(b1 && b2){
+ vec5 = this.getWalkablePosition(vec.add(1, 0, 1));
+ if(!vec5.equals(a) && !vec5.equals(b)){
+ neighbors.add(this.grid.getNode(vec5));
+ }
+ }
+ if(b2 && b3){
+ vec6 = this.getWalkablePosition(vec.add(-1, 0, 1));
+ if(!vec6.equals(a) && !vec6.equals(b)){
+ neighbors.add(this.grid.getNode(vec6));
+ }
+ }
+ if(b3 && b4){
+ vec7 = this.getWalkablePosition(vec.add(-1, 0, -1));
+ if(!vec7.equals(a) && !vec7.equals(b)){
+ neighbors.add(this.grid.getNode(vec7));
+ }
+ }
+ if(b4 && b1){
+ vec8 = this.getWalkablePosition(vec.add(1, 0, -1));
+ if(!vec8.equals(a) && !vec8.equals(b)){
+ neighbors.add(this.grid.getNode(vec8));
+ }
+ }
+ return neighbors;
+ }
+
+ public Vector3 getWalkablePosition(Vector3 vec){
+ if(this.grid.hasNode(vec)){
+ return vec;
+ }
+ int block = map.get(vec.add(0, 1, 0));
+ int block1 = map.get(vec.add(0, 2, 0));
+ int block2;
+ if(map.get(vec) == 2){
+ for(double i = vec.y + 1; i < 255; i++){
+ Vector3 v = new Vector3(vec.x, i, vec.z);
+ if(map.get(v) == 0){
+ return v.add(0, -1, 0);
+ }
+ if(map.get(v) == 1){
+ break;
+ }
+ }
+ return vec;
+ }
+ for(double i = vec.y; i > 0; i--){
+ Vector3 v = new Vector3(vec.x, i, vec.z);
+ block2 = map.get(v);
+ if(block == 0){
+ if(this.canWalkOn(block, block1, block2)){
+ return v.add(0, 1, 0);
+ }
+ }else{
+ return new Vector3(-1, -101, -1);
+ }
+ block1 = block;
+ block = block2;
+ }
+ return new Vector3(-1, -100, -1);
+ }
+
+ private boolean canWalkOn(int block, int block1, int block2){
+ if(block1 == 0 || block1 == 0){
+ if(block2 == 1){
+ return true;
+ }/*
+ * else{ if(this.getEntity() instanceof Swimable && (id == Block.WATER || id ==
+ * Block.STILL_WATER)){ if(block.getId() != 0){ return true; } } }
+ */
+ }
+ return false;
+ }
+
+ /*private double heuristic(Vector3 one, Vector3 two){
+ double dx = Math.abs(one.x - two.x);
+ double dy = Math.abs(one.y - two.y);
+ double dz = Math.abs(one.z - two.z);
+
+ double max = Math.max(dx, dz);
+ double min = Math.min(dx, dz);
+
+ return 0.414 * min + max + dy;
+ }*/
+
+ @Override
+ public synchronized void resetNodes(){
+ super.resetNodes();
+ }
+
+ @Override
+ public boolean research(){
+ this.resetNodes();
+ return this.search();
+ }
+
+ @Override
+ public boolean isSearching(){
+ return this.searching;
+ }
+
+ @Override
+ public boolean isSuccess(){
+ return this.succeed;
+ }
+}
diff --git a/src/main/java/cn/dxp/route/Grid.java b/src/main/java/cn/dxp/route/Grid.java
new file mode 100644
index 0000000..5a41750
--- /dev/null
+++ b/src/main/java/cn/dxp/route/Grid.java
@@ -0,0 +1,46 @@
+package cn.dxp.route;
+
+import cn.dxp.math.*;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+public class Grid{
+ private ConcurrentHashMap>> grid =
+ new ConcurrentHashMap>>();
+
+ public void clear(){
+ grid.clear();
+ }
+
+ public void putNode(Node node){
+ Vector3 vec = node.getVector3().floor();
+ if(!grid.containsKey(vec.x)){
+ grid.put(vec.x, new ConcurrentHashMap>());
+ }
+ ConcurrentHashMap> gx = grid.get(vec.x);
+ if(!gx.containsKey(vec.y)){
+ gx.put(vec.y, new ConcurrentHashMap());
+ }
+ gx.get(vec.y).put(vec.z, node);
+ }
+
+ public Node getNode(Vector3 vec){
+ vec = vec.floor();
+ if(!grid.containsKey(vec.x) || !grid.get(vec.x).containsKey(vec.y)
+ || !grid.get(vec.x).get(vec.y).containsKey(vec.z)){
+ Node node = new Node(vec.x, vec.y, vec.z);
+ this.putNode(node);
+ return node;
+ }
+ return grid.get(vec.x).get(vec.y).get(vec.z);
+ }
+
+ public boolean hasNode(Vector3 vec){
+ vec = vec.floor();
+ if(!grid.containsKey(vec.x) || !grid.get(vec.x).containsKey(vec.y)
+ || !grid.get(vec.x).get(vec.y).containsKey(vec.z)){
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/src/main/java/cn/dxp/route/Node.java b/src/main/java/cn/dxp/route/Node.java
new file mode 100644
index 0000000..49ce396
--- /dev/null
+++ b/src/main/java/cn/dxp/route/Node.java
@@ -0,0 +1,64 @@
+package cn.dxp.route;
+
+import cn.dxp.math.Vector3;
+
+public class Node{
+ private Node parent = null;
+ public boolean closed = false;
+
+ private Vector3 node;
+ public double f = -1;
+ public double g = -1;
+
+ public Node(double x, double y, double z){
+ this.node = new Vector3(x, y, z);
+ }
+
+ public Node(Vector3 vec){
+ if(vec == null){
+ throw new IllegalArgumentException("Node cannot be null");
+ }
+
+ this.node = new Vector3(vec.x, vec.y, vec.z);
+ }
+
+ public Vector3 getVector3(){
+ return new Vector3(node.x, node.y, node.z);
+ }
+
+ public Vector3 getRawVector3(){
+ return this.node;
+ }
+
+ public double getX(){
+ return this.node.x;
+ }
+
+ public double getY(){
+ return this.node.y;
+ }
+
+ public double getZ(){
+ return this.node.z;
+ }
+
+ public void add(double x, double y, double z){
+ this.node = this.node.add(x, y, z);
+ }
+
+ public String toString(){
+ return "Node (x=" + this.node.x + ", y=" + this.node.y + ", " + this.node.z + ")";
+ }
+
+ public void setParent(Node node){
+ this.parent = node;
+ }
+
+ public Node getParent(){
+ return this.parent;
+ }
+
+ public boolean equals(Node node){
+ return this.getVector3().equals(node.getVector3());
+ }
+}
diff --git a/src/main/java/cn/dxp/route/RouteFinder.java b/src/main/java/cn/dxp/route/RouteFinder.java
new file mode 100644
index 0000000..86da579
--- /dev/null
+++ b/src/main/java/cn/dxp/route/RouteFinder.java
@@ -0,0 +1,127 @@
+package cn.dxp.route;
+
+import cn.dxp.*;
+import cn.dxp.math.*;
+
+import java.util.*;
+
+public abstract class RouteFinder{
+ private int current = 0;
+ protected Vector3 destination = null, start = null;
+ protected ArrayList nodes = new ArrayList();
+ protected boolean forceStop = false;
+ private boolean arrived = false;
+ public long stopRouteFindUntil = System.currentTimeMillis();
+ public boolean firstSearch = false;
+
+ public HashMap map;
+ private Entity entity;
+ public PhysicalRealTimeRouteFinder prtrf;
+ public RouteTask rtask;
+ public long startTime;
+
+ public RouteFinder(PhysicalRealTimeRouteFinder prtrf, HashMap m,
+ Entity entity, int threadCount){
+ this.map = m;
+ this.entity = entity;
+ this.prtrf = prtrf;
+ }
+
+ public void setEntity(Entity e){
+ this.entity = e;
+ }
+
+ public Entity getEntity(){
+ return this.entity;
+ }
+
+ public void setStart(Vector3 start){
+ this.start = start.clone();
+ }
+
+ public Vector3 getStart(){
+ return (this.firstSearch ?start : this.entity);
+ }
+
+ public void setDestination(Vector3 destination){
+ this.destination = destination.clone();
+ }
+
+ public Vector3 getDestination(){
+ return destination;
+ }
+
+ protected void resetNodes(){
+ this.nodes.clear();
+ this.arrived = false;
+ this.current = 0;
+ }
+
+ public void forceStop(){
+ this.forceStop = true;
+ if(!this.isSearching()){
+ this.forceStop = false;
+ this.resetNodes();
+ }
+ }
+
+ public void addNode(Node node){
+ this.nodes.add(node);
+ }
+
+ public void addNodes(ArrayList node){
+ this.nodes.addAll(node);
+ }
+
+ public boolean hasNext(){
+ return !this.arrived && nodes.size() > this.current + 1;
+ }
+
+ public boolean next(){
+ if(this.hasNext()){
+ this.current++;
+ return true;
+ }
+ return false;
+ }
+
+ public boolean hasReachedNode(Vector3 vec){
+ Vector3 cur = this.get().getVector3();
+ return vec.x == cur.x && vec.y == cur.y && vec.z == cur.z;
+ }
+
+ public Node get(){
+ if(nodes.size() == 0){
+ if(this.getDestination() != null){
+ return new Node(this.getDestination());
+ }else{
+ throw new IllegalStateException("There is no path found.");
+ }
+ }
+ if(this.arrived)
+ return null;
+ return nodes.get(current);
+ }
+
+ public void arrived(){
+ this.current = 0;
+ this.arrived = true;
+ }
+
+ public boolean hasRoute(){
+ return this.nodes.size() > 0;
+ }
+
+ public void taskSearch(){
+ this.rtask = new RouteTask(this);
+ this.rtask.start();
+ }
+
+ public abstract boolean search();
+
+ public abstract boolean research();
+
+ public abstract boolean isSearching();
+
+ public abstract boolean isSuccess();
+}
diff --git a/src/main/java/cn/dxp/route/RouteTask.java b/src/main/java/cn/dxp/route/RouteTask.java
new file mode 100644
index 0000000..553969e
--- /dev/null
+++ b/src/main/java/cn/dxp/route/RouteTask.java
@@ -0,0 +1,34 @@
+package cn.dxp.route;
+
+import java.util.*;
+
+public class RouteTask extends Thread{
+
+ public RouteFinder route;
+
+ public RouteTask(RouteFinder route){
+ this.route = route;
+ }
+
+ @Override
+ public void run(){
+ try{
+ while(true){
+ this.route.research();
+ if(!this.route.isSuccess()){
+ System.out.println("寻路超时");
+ continue;
+ }
+ long usedTime = System.currentTimeMillis() - this.route.startTime;
+ HashMap fdata = new HashMap();
+ HashMap idata = new HashMap();
+ idata.put("FrameCalculateTime", usedTime);
+ fdata.put("Route", this.route.nodes);
+ fdata.put("Info", idata);
+ this.route.prtrf.addNewFrame(fdata);
+ }
+ }catch (Exception e){
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/target/PhysicalRealTimeRouteFinder-1.0-SNAPSHOT-shaded.jar b/target/PhysicalRealTimeRouteFinder-1.0-SNAPSHOT-shaded.jar
new file mode 100644
index 0000000..1672bea
Binary files /dev/null and b/target/PhysicalRealTimeRouteFinder-1.0-SNAPSHOT-shaded.jar differ
diff --git a/target/PhysicalRealTimeRouteFinder-1.0-SNAPSHOT.jar b/target/PhysicalRealTimeRouteFinder-1.0-SNAPSHOT.jar
new file mode 100644
index 0000000..1672bea
Binary files /dev/null and b/target/PhysicalRealTimeRouteFinder-1.0-SNAPSHOT.jar differ
diff --git a/target/classes/cn/dxp/PRTRF.class b/target/classes/cn/dxp/PRTRF.class
new file mode 100644
index 0000000..009f156
Binary files /dev/null and b/target/classes/cn/dxp/PRTRF.class differ
diff --git a/target/classes/cn/dxp/PhysicalRealTimeRouteFinder.class b/target/classes/cn/dxp/PhysicalRealTimeRouteFinder.class
new file mode 100644
index 0000000..1faa431
Binary files /dev/null and b/target/classes/cn/dxp/PhysicalRealTimeRouteFinder.class differ
diff --git a/target/classes/cn/dxp/map/MapGenerator.class b/target/classes/cn/dxp/map/MapGenerator.class
new file mode 100644
index 0000000..d4e87bf
Binary files /dev/null and b/target/classes/cn/dxp/map/MapGenerator.class differ
diff --git a/target/classes/cn/dxp/math/Entity.class b/target/classes/cn/dxp/math/Entity.class
new file mode 100644
index 0000000..6b4dc8d
Binary files /dev/null and b/target/classes/cn/dxp/math/Entity.class differ
diff --git a/target/classes/cn/dxp/math/Vector3.class b/target/classes/cn/dxp/math/Vector3.class
new file mode 100644
index 0000000..4dfe674
Binary files /dev/null and b/target/classes/cn/dxp/math/Vector3.class differ
diff --git a/target/classes/cn/dxp/network/HttpSender$1.class b/target/classes/cn/dxp/network/HttpSender$1.class
new file mode 100644
index 0000000..5c64e7d
Binary files /dev/null and b/target/classes/cn/dxp/network/HttpSender$1.class differ
diff --git a/target/classes/cn/dxp/network/HttpSender.class b/target/classes/cn/dxp/network/HttpSender.class
new file mode 100644
index 0000000..a7b9a4b
Binary files /dev/null and b/target/classes/cn/dxp/network/HttpSender.class differ
diff --git a/target/classes/cn/dxp/route/AdvancedRouteFinder.class b/target/classes/cn/dxp/route/AdvancedRouteFinder.class
new file mode 100644
index 0000000..cbd9b31
Binary files /dev/null and b/target/classes/cn/dxp/route/AdvancedRouteFinder.class differ
diff --git a/target/classes/cn/dxp/route/Grid.class b/target/classes/cn/dxp/route/Grid.class
new file mode 100644
index 0000000..96a8d71
Binary files /dev/null and b/target/classes/cn/dxp/route/Grid.class differ
diff --git a/target/classes/cn/dxp/route/Node.class b/target/classes/cn/dxp/route/Node.class
new file mode 100644
index 0000000..c24da73
Binary files /dev/null and b/target/classes/cn/dxp/route/Node.class differ
diff --git a/target/classes/cn/dxp/route/RouteFinder.class b/target/classes/cn/dxp/route/RouteFinder.class
new file mode 100644
index 0000000..747a580
Binary files /dev/null and b/target/classes/cn/dxp/route/RouteFinder.class differ
diff --git a/target/classes/cn/dxp/route/RouteTask.class b/target/classes/cn/dxp/route/RouteTask.class
new file mode 100644
index 0000000..fb4e616
Binary files /dev/null and b/target/classes/cn/dxp/route/RouteTask.class differ
diff --git a/target/maven-archiver/pom.properties b/target/maven-archiver/pom.properties
new file mode 100644
index 0000000..711e1b5
--- /dev/null
+++ b/target/maven-archiver/pom.properties
@@ -0,0 +1,5 @@
+#Generated by Maven
+#Mon May 10 14:25:53 CST 2021
+groupId=cn.dxp
+artifactId=PhysicalRealTimeRouteFinder
+version=1.0-SNAPSHOT
diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
new file mode 100644
index 0000000..e69de29
diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
new file mode 100644
index 0000000..9b710f9
--- /dev/null
+++ b/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
@@ -0,0 +1,11 @@
+e:\PhysicalRealTimeRouteFinder\src\main\java\cn\dxp\PRTRF.java
+e:\PhysicalRealTimeRouteFinder\src\main\java\cn\dxp\route\Grid.java
+e:\PhysicalRealTimeRouteFinder\src\main\java\cn\dxp\route\AdvancedRouteFinder.java
+e:\PhysicalRealTimeRouteFinder\src\main\java\cn\dxp\route\RouteTask.java
+e:\PhysicalRealTimeRouteFinder\src\main\java\cn\dxp\math\Vector3.java
+e:\PhysicalRealTimeRouteFinder\src\main\java\cn\dxp\network\HttpSender.java
+e:\PhysicalRealTimeRouteFinder\src\main\java\cn\dxp\route\Node.java
+e:\PhysicalRealTimeRouteFinder\src\main\java\cn\dxp\PhysicalRealTimeRouteFinder.java
+e:\PhysicalRealTimeRouteFinder\src\main\java\cn\dxp\route\RouteFinder.java
+e:\PhysicalRealTimeRouteFinder\src\main\java\cn\dxp\map\MapGenerator.java
+e:\PhysicalRealTimeRouteFinder\src\main\java\cn\dxp\math\Entity.java
diff --git a/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst b/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst
new file mode 100644
index 0000000..14f9111
--- /dev/null
+++ b/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst
@@ -0,0 +1 @@
+cn\dxp\AppTest.class
diff --git a/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
new file mode 100644
index 0000000..8ac3569
--- /dev/null
+++ b/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
@@ -0,0 +1 @@
+E:\PhysicalRealTimeRouteFinder\src\test\java\cn\dxp\AppTest.java
diff --git a/target/original-PhysicalRealTimeRouteFinder-1.0-SNAPSHOT.jar b/target/original-PhysicalRealTimeRouteFinder-1.0-SNAPSHOT.jar
new file mode 100644
index 0000000..b476550
Binary files /dev/null and b/target/original-PhysicalRealTimeRouteFinder-1.0-SNAPSHOT.jar differ
diff --git a/target/surefire-reports/TEST-cn.dxp.AppTest.xml b/target/surefire-reports/TEST-cn.dxp.AppTest.xml
new file mode 100644
index 0000000..7d830f8
--- /dev/null
+++ b/target/surefire-reports/TEST-cn.dxp.AppTest.xml
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/target/surefire-reports/cn.dxp.AppTest.txt b/target/surefire-reports/cn.dxp.AppTest.txt
new file mode 100644
index 0000000..2faf6f2
--- /dev/null
+++ b/target/surefire-reports/cn.dxp.AppTest.txt
@@ -0,0 +1,4 @@
+-------------------------------------------------------------------------------
+Test set: cn.dxp.AppTest
+-------------------------------------------------------------------------------
+Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.012 sec