diff --git a/client/pom.xml b/client/pom.xml
index 1f1b532..e14b86d 100644
--- a/client/pom.xml
+++ b/client/pom.xml
@@ -57,6 +57,10 @@
org.slf4j
slf4j-log4j12
+
+ junit
+ junit
+
org.controlsfx
controlsfx
diff --git a/client/src/main/java/ru/trader/controllers/SystemsEditorController.java b/client/src/main/java/ru/trader/controllers/SystemsEditorController.java
index e12cd1e..ec22cd4 100644
--- a/client/src/main/java/ru/trader/controllers/SystemsEditorController.java
+++ b/client/src/main/java/ru/trader/controllers/SystemsEditorController.java
@@ -20,6 +20,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.trader.model.MarketModel;
import ru.trader.model.SystemModel;
+import ru.trader.model.support.PositionComputer;
import ru.trader.view.support.Localization;
import ru.trader.view.support.cells.TextFieldCell;
@@ -83,6 +84,13 @@ public class SystemsEditorController {
clnS6.setCellFactory(TextFieldCell.forTableColumn(new DoubleStringConverter()));
tblSystems.setItems(FXCollections.observableArrayList());
tblSystems.getSelectionModel().setCellSelectionEnabled(true);
+ tblSystems.setSortPolicy(t -> true);
+ system1.valueProperty().addListener((ov, o, n) -> clnS1.setText(n != null ? n.getName() : ""));
+ system2.valueProperty().addListener((ov, o, n) -> clnS2.setText(n != null ? n.getName() : ""));
+ system3.valueProperty().addListener((ov, o, n) -> clnS3.setText(n != null ? n.getName() : ""));
+ system4.valueProperty().addListener((ov, o, n) -> clnS4.setText(n != null ? n.getName() : ""));
+ system5.valueProperty().addListener((ov, o, n) -> clnS5.setText(n != null ? n.getName() : ""));
+ system6.valueProperty().addListener((ov, o, n) -> clnS6.setText(n != null ? n.getName() : ""));
init();
}
@@ -111,10 +119,33 @@ public class SystemsEditorController {
reset();
}
- public void add() {
+ public void add(){
tblSystems.getItems().add(new SystemData());
}
+ public void compute(){
+ SystemModel sys1 = system1.getValue();
+ SystemModel sys2 = system2.getValue();
+ SystemModel sys3 = system3.getValue();
+ SystemModel sys4 = system4.getValue();
+ SystemModel sys5 = system5.getValue();
+ SystemModel sys6 = system6.getValue();
+
+ for (SystemData systemData : tblSystems.getItems()) {
+ if (systemData.name.isEmpty().get()) continue;
+ PositionComputer computer = new PositionComputer();
+ if (sys1 != null) computer.addLandMark(sys1, systemData.s1.get());
+ if (sys2 != null) computer.addLandMark(sys2, systemData.s2.get());
+ if (sys3 != null) computer.addLandMark(sys3, systemData.s3.get());
+ if (sys4 != null) computer.addLandMark(sys4, systemData.s4.get());
+ if (sys5 != null) computer.addLandMark(sys5, systemData.s5.get());
+ if (sys6 != null) computer.addLandMark(sys6, systemData.s6.get());
+ PositionComputer.Coordinates coord = computer.compute();
+ systemData.x.set(coord.getX());
+ systemData.y.set(coord.getY());
+ systemData.z.set(coord.getZ());
+ }
+ }
private void commit(){
for (SystemData systemData : tblSystems.getItems()) {
@@ -196,8 +227,12 @@ public class SystemsEditorController {
return s6;
}
+ public boolean isEmpty(){
+ return name.get().isEmpty() || Double.isNaN(x.get()) || Double.isNaN(y.get()) || Double.isNaN(z.get());
+ }
+
private void commit(){
- if (!name.get().isEmpty() && !Double.isNaN(x.get()) && !Double.isNaN(y.get()) && !Double.isNaN(z.get())){
+ if (!isEmpty()){
if (system != null){
system.setName(name.get());
system.setPosition(x.get(), y.get(), z.get());
diff --git a/client/src/main/java/ru/trader/model/support/PositionComputer.java b/client/src/main/java/ru/trader/model/support/PositionComputer.java
new file mode 100644
index 0000000..d076986
--- /dev/null
+++ b/client/src/main/java/ru/trader/model/support/PositionComputer.java
@@ -0,0 +1,125 @@
+package ru.trader.model.support;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import ru.trader.model.SystemModel;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class PositionComputer {
+ private final static Logger LOG = LoggerFactory.getLogger(PositionComputer.class);
+
+ private final static double MAX_ERROR = 1E-10;
+ private final static double MAX_VALUE = 1000;
+ private final static double MIN_VALUE = -1000;
+
+ private final List marks = new ArrayList<>(6);
+ private final List distances = new ArrayList<>(6);
+
+ public PositionComputer() {
+ }
+
+ public void addLandMark(SystemModel system, double distance){
+ marks.add(system);
+ distances.add(distance);
+ }
+
+
+ public Coordinates compute(){
+ return compute(MIN_VALUE, MIN_VALUE, MIN_VALUE);
+ }
+
+ public Coordinates compute(final double x, final double y, final double z){
+ Coordinates res = new Coordinates(Double.NaN, Double.NaN, Double.NaN);
+ Coordinates current = new Coordinates(x, y, z);
+ double xmin = MIN_VALUE, xmax = MAX_VALUE;
+ double ymin = MIN_VALUE, ymax = MAX_VALUE;
+ double zmin = MIN_VALUE, zmax = MAX_VALUE;
+ double step=100, mineps = Double.NaN;
+
+ while (true){
+ double delta = 0;
+ for (int i = 0; i < marks.size(); i++) {
+ delta += Math.abs(marks.get(i).getDistance(current.x, current.y, current.z) - distances.get(i));
+ }
+ LOG.trace("coordinates = {}, delta = {}", current, delta);
+ if (delta < MAX_ERROR) {
+ res = current;
+ LOG.debug("Coordinates found {}", res);
+ break;
+ }
+ if (Double.isNaN(mineps) || delta < mineps){
+ mineps = delta;
+ res = new Coordinates(current);
+ }
+
+ current.x += step;
+ if (current.x >= xmax){
+ current.x = xmin;
+ current.y += step;
+ if (current.y >= ymax){
+ current.y = ymin;
+ current.z += step;
+ if (current.z >= zmax){
+ if (step < MAX_ERROR){
+ LOG.debug("Coordinates not found, last {}, delta {}", res, mineps);
+ break;
+ } else {
+ xmin = res.x - step*2; xmax = res.x + step*2; current.x = xmin;
+ ymin = res.y - step*2; ymax = res.y + step*2; current.y = ymin;
+ zmin = res.z - step*2; zmax = res.z + step*2; current.z = zmin;
+ step = step/2;
+ LOG.trace("Change step to {}", step);
+ mineps = Double.NaN;
+ }
+ }
+ }
+ }
+
+ }
+
+ return res;
+ }
+
+
+ public class Coordinates {
+ private double x;
+ private double y;
+ private double z;
+
+ public Coordinates(double x, double y, double z) {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ }
+
+ public Coordinates(Coordinates other) {
+ this.x = other.x;
+ this.y = other.y;
+ this.z = other.z;
+ }
+
+ public double getX() {
+ return x;
+ }
+
+ public double getY() {
+ return y;
+ }
+
+ public double getZ() {
+ return z;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("{");
+ sb.append("x=").append(x);
+ sb.append(", y=").append(y);
+ sb.append(", z=").append(z);
+ sb.append('}');
+ return sb.toString();
+ }
+ }
+}
diff --git a/client/src/main/resources/view/sEditor.fxml b/client/src/main/resources/view/sEditor.fxml
index c27279e..04ee54e 100644
--- a/client/src/main/resources/view/sEditor.fxml
+++ b/client/src/main/resources/view/sEditor.fxml
@@ -30,7 +30,16 @@
-
+
+
+
+
+
+
diff --git a/client/src/test/java/ru/trader/model/support/PositionComputerTest.java b/client/src/test/java/ru/trader/model/support/PositionComputerTest.java
new file mode 100644
index 0000000..81120fa
--- /dev/null
+++ b/client/src/test/java/ru/trader/model/support/PositionComputerTest.java
@@ -0,0 +1,94 @@
+package ru.trader.model.support;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import ru.trader.core.Market;
+import ru.trader.model.MarketModel;
+import ru.trader.model.SystemModel;
+import ru.trader.store.simple.SimpleMarket;
+
+public class PositionComputerTest extends Assert {
+ private final static Logger LOG = LoggerFactory.getLogger(PositionComputerTest.class);
+ private SystemModel system1;
+ private SystemModel system2;
+ private SystemModel system3;
+ private SystemModel system4;
+ private SystemModel system5;
+ private SystemModel system6;
+ private SystemModel system7;
+ private SystemModel system8;
+
+ @Before
+ public void setUp() throws Exception {
+ LOG.info("Set up test compute");
+ Market market = new SimpleMarket();
+ market.addPlace("System1", -13.3438, 53.7812, 12.5625);
+ market.addPlace("System2", -7.9062, 34.7188, 2.125);
+ market.addPlace("System3", -4.8438, 26.6562, -4.7812);
+ market.addPlace("System4", -27.0938, 21.625, 0.7812);
+ market.addPlace("System5", -22.6875, 25.8125, -6.6875);
+ market.addPlace("System6", -106.25, 33.5938, -61);
+ market.addPlace("System7", -50.75, 50.0312, -13.2813);
+ market.addPlace("Sol", 0, 0, 0);
+ MarketModel marketModel = new MarketModel(market);
+ system1 = marketModel.systemsProperty().get(0);
+ system2 = marketModel.systemsProperty().get(1);
+ system3 = marketModel.systemsProperty().get(2);
+ system4 = marketModel.systemsProperty().get(3);
+ system5 = marketModel.systemsProperty().get(4);
+ system6 = marketModel.systemsProperty().get(5);
+ system7 = marketModel.systemsProperty().get(6);
+ system8 = marketModel.systemsProperty().get(7);
+ }
+
+ @Test
+ public void testCompute() throws Exception {
+ LOG.info("Start test compute");
+ PositionComputer computer = new PositionComputer();
+ computer.addLandMark(system1, system1.getDistance(system7));
+ computer.addLandMark(system2, system2.getDistance(system7));
+ computer.addLandMark(system3, system3.getDistance(system7));
+ computer.addLandMark(system4, system4.getDistance(system7));
+ computer.addLandMark(system5, system5.getDistance(system7));
+ computer.addLandMark(system6, system6.getDistance(system7));
+ PositionComputer.Coordinates coordinates = computer.compute();
+ assertEquals(system7.getX(), coordinates.getX(), 0.0000001);
+ assertEquals(system7.getY(), coordinates.getY(), 0.0000001);
+ assertEquals(system7.getZ(), coordinates.getZ(), 0.0000001);
+ }
+
+ @Test
+ public void testCompute2() throws Exception {
+ LOG.info("Start test compute2");
+ PositionComputer computer = new PositionComputer();
+ computer.addLandMark(system1, system1.getDistance(system3));
+ computer.addLandMark(system2, system2.getDistance(system3));
+ computer.addLandMark(system7, system7.getDistance(system3));
+ computer.addLandMark(system4, system4.getDistance(system3));
+ computer.addLandMark(system5, system5.getDistance(system3));
+ computer.addLandMark(system6, system6.getDistance(system3));
+ PositionComputer.Coordinates coordinates = computer.compute();
+ assertEquals(system3.getX(), coordinates.getX(), 0.0000001);
+ assertEquals(system3.getY(), coordinates.getY(), 0.0000001);
+ assertEquals(system3.getZ(), coordinates.getZ(), 0.0000001);
+ }
+
+ @Test
+ public void testCompute3() throws Exception {
+ LOG.info("Start test compute3");
+ PositionComputer computer = new PositionComputer();
+ computer.addLandMark(system1, system1.getDistance(system8));
+ computer.addLandMark(system2, system2.getDistance(system8));
+ computer.addLandMark(system7, system7.getDistance(system8));
+ computer.addLandMark(system4, system4.getDistance(system8));
+ computer.addLandMark(system5, system5.getDistance(system8));
+ computer.addLandMark(system6, system6.getDistance(system8));
+ PositionComputer.Coordinates coordinates = computer.compute();
+ assertEquals(system8.getX(), coordinates.getX(), 0.0000001);
+ assertEquals(system8.getY(), coordinates.getY(), 0.0000001);
+ assertEquals(system8.getZ(), coordinates.getZ(), 0.0000001);
+ }
+}
diff --git a/client/src/test/resources/log4j.properties b/client/src/test/resources/log4j.properties
new file mode 100644
index 0000000..fe6a143
--- /dev/null
+++ b/client/src/test/resources/log4j.properties
@@ -0,0 +1,7 @@
+log4j.rootLogger = INFO, stdout
+
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%p: %d{dd.MM.yyyy HH:mm:ss} (%F:%L) - %m%n
+
+