From 99444484787bd9fb200d951de7bc808f576cdba4 Mon Sep 17 00:00:00 2001 From: "Christopher Ronnewinkel (D036654)" Date: Sat, 5 Apr 2014 13:18:03 +0200 Subject: [PATCH] add border to wind field in order to enlarge area covered by wind visualization; --- .../gwt/ui/server/SimulatorServiceImpl.java | 11 +++-- .../gwt/ui/shared/WindFieldGenParamsDTO.java | 15 +++++++ .../gwt/ui/simulator/SimulatorEntryPoint.java | 9 +++- .../gwt/ui/simulator/SimulatorMainPanel.java | 4 +- .../gwt/ui/simulator/SimulatorMap.java | 9 +++- .../WindStreamletsCanvasOverlay.java | 12 +++--- .../simulator/util/ColorPaletteGenerator.java | 2 +- .../com.sap.sailing.gwt.ui/wind-streamlets.js | 39 ++++++++++-------- .../test/RectangularBoundaryTest.java | 2 +- .../sailing/simulator/test/SimulatorTest.java | 2 +- .../sailing/simulator/test/TreeGrowTest.java | 2 +- .../test/WindFieldGeneratorTest.java | 8 ++-- .../com/sap/sailing/simulator/Boundary.java | 7 +++- .../simulator/impl/PathGeneratorDijkstra.java | 2 +- .../impl/PathGeneratorDynProgForward.java | 2 +- .../simulator/impl/RectangularBoundary.java | 41 +++++++++++++------ .../simulator/impl/SailingSimulatorImpl.java | 2 +- .../WindFieldGeneratorOscillationImpl.java | 10 ++++- 18 files changed, 122 insertions(+), 57 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SimulatorServiceImpl.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SimulatorServiceImpl.java index 227c744d39f..907931e80f6 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SimulatorServiceImpl.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SimulatorServiceImpl.java @@ -199,7 +199,7 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula throw new WindPatternNotFoundException("Please select a valid wind pattern."); } - Position[][] grid = bd.extractGrid(params.getxRes(), params.getyRes()); + Position[][] grid = bd.extractGrid(params.getxRes(), params.getyRes(), params.getBorderY(), params.getBorderX()); wf.setPositionGrid(grid); TimePoint startTime = new MillisecondsTimePoint(params.getStartTime().getTime());// new @@ -274,9 +274,11 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula wf.setGridAreaGps(gridAreaGps); } - int[] gridRes = new int[2]; + int[] gridRes = new int[4]; gridRes[0] = params.getxRes(); gridRes[1] = params.getyRes(); + gridRes[2] = params.getBorderY(); + gridRes[3] = params.getBorderX(); wf.setGridResolution(gridRes); wf.generate(startTime, null, timeStep); @@ -771,11 +773,14 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula // SouthWest jsonField += "boundsSW:{lat:" + positionGrid[0][0].getLatDeg() + ",lng:" + positionGrid[0][0].getLngDeg() + "},"; // NorthEast - jsonField += "boundsNE:{lat:" + positionGrid[params.getyRes()-1][params.getxRes()-1].getLatDeg() + ",lng:" + positionGrid[params.getyRes()-1][params.getxRes()-1].getLngDeg() + "},"; + jsonField += "boundsNE:{lat:" + positionGrid[params.getyRes()+2*params.getBorderY()-1][params.getxRes()+2*params.getBorderX()-1].getLatDeg() + ",lng:" + positionGrid[params.getyRes()+2*params.getBorderY()-1][params.getxRes()+2*params.getBorderX()-1].getLngDeg() + "},"; //this.resY = field.resY; jsonField += "resY:" + params.getyRes() + ","; //this.resX = field.resX; jsonField += "resX:" + params.getxRes() + ","; + // border + jsonField += "borderY:" + params.getBorderY() + ","; + jsonField += "borderX:" + params.getBorderX() + ","; //this.xScale = field.xScale; jsonField += "xScale:1.5,"; diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/WindFieldGenParamsDTO.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/WindFieldGenParamsDTO.java index a9f36f721c3..736d87e169a 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/WindFieldGenParamsDTO.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/WindFieldGenParamsDTO.java @@ -12,6 +12,8 @@ public class WindFieldGenParamsDTO implements IsSerializable { private int xRes; private int yRes; + private int borderY; + private int borderX; private Date startTime; private Date endTime; @@ -80,6 +82,19 @@ public class WindFieldGenParamsDTO implements IsSerializable { this.yRes = yRes; } + public int getBorderY() { + return borderY; + } + + public int getBorderX() { + return borderX; + } + + public void setBorder(int border) { + this.borderY = border; + this.borderX = (int)Math.round(border * ((double)xRes) / ((double)yRes)); + } + public Date getStartTime() { return startTime; } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/simulator/SimulatorEntryPoint.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/simulator/SimulatorEntryPoint.java index c6ed10548c0..5d224d75bb5 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/simulator/SimulatorEntryPoint.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/simulator/SimulatorEntryPoint.java @@ -24,6 +24,7 @@ public class SimulatorEntryPoint extends AbstractEntryPoint { private final SimulatorServiceAsync simulatorService = GWT.create(SimulatorService.class); private int xRes = 40; private int yRes = 20; + private int border = 10; private boolean autoUpdate = false; private char mode = SailingSimulatorConstants.ModeEvent; // default mode: 'e'vent private char event = SailingSimulatorConstants.EventKielerWoche; // default event: 'k'ieler woche @@ -68,6 +69,12 @@ public class SimulatorEntryPoint extends AbstractEntryPoint { } else { yRes = Integer.parseInt(verticalRes); } + String border = Window.Location.getParameter("border"); + if (border == null || border.isEmpty()) { + logger.config("Using default border " + this.border); + } else { + this.border = Integer.parseInt(border); + } String autoUpdateStr = Window.Location.getParameter("autoUpdate"); if (autoUpdateStr == null || autoUpdateStr.isEmpty()) { logger.config("Using default auto update " + autoUpdate); @@ -153,7 +160,7 @@ public class SimulatorEntryPoint extends AbstractEntryPoint { } private void createSimulatorPanel() { - SimulatorMainPanel simulatorPanel = new SimulatorMainPanel(simulatorService, stringMessages, this, xRes, yRes, + SimulatorMainPanel simulatorPanel = new SimulatorMainPanel(simulatorService, stringMessages, this, xRes, yRes, border, autoUpdate, mode, event, showGrid, showLines, seedLines, showArrows, showStreamlets, showStreamlets2, injectWindDataJS); DockLayoutPanel p = new DockLayoutPanel(Unit.PX); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/simulator/SimulatorMainPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/simulator/SimulatorMainPanel.java index 5e330177ae7..ebe5055a19c 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/simulator/SimulatorMainPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/simulator/SimulatorMainPanel.java @@ -225,7 +225,7 @@ public class SimulatorMainPanel extends SimplePanel { return NumberFormat.getFormat("0.0").format(value); } - public SimulatorMainPanel(SimulatorServiceAsync svc, StringMessages stringMessages, ErrorReporter errorReporter, int xRes, int yRes, boolean autoUpdate, + public SimulatorMainPanel(SimulatorServiceAsync svc, StringMessages stringMessages, ErrorReporter errorReporter, int xRes, int yRes, int border, boolean autoUpdate, char mode, char event, boolean showGrid, boolean showLines, char seedLines, boolean showArrows, boolean showStreamlets, boolean showStreamlets2, boolean injectWindDataJS) { super(); @@ -310,7 +310,7 @@ public class SimulatorMainPanel extends SimplePanel { busyIndicator = new SimpleBusyIndicator(false, 0.8f); - simulatorMap = new SimulatorMap(simulatorSvc, stringMessages, errorReporter, xRes, yRes, timer, timePanel, + simulatorMap = new SimulatorMap(simulatorSvc, stringMessages, errorReporter, xRes, yRes, border, timer, timePanel, windParams, busyIndicator, mode, this); simulatorMap.setSize("100%", "100%"); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/simulator/SimulatorMap.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/simulator/SimulatorMap.java index 400f6eec144..899236711f6 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/simulator/SimulatorMap.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/simulator/SimulatorMap.java @@ -97,6 +97,7 @@ public class SimulatorMap extends AbsolutePanel implements RequiresDataInitializ private ColorPalette colorPalette; private int xRes; private int yRes; + private int border; private boolean warningAlreadyShown = false; private SimulatorMainPanel parent = null; private PathPolyline pathPolyline = null; @@ -288,7 +289,7 @@ public class SimulatorMap extends AbsolutePanel implements RequiresDataInitializ } - public SimulatorMap(SimulatorServiceAsync simulatorSvc, StringMessages stringMessages, ErrorReporter errorReporter, int xRes, int yRes, Timer timer, + public SimulatorMap(SimulatorServiceAsync simulatorSvc, StringMessages stringMessages, ErrorReporter errorReporter, int xRes, int yRes, int border, Timer timer, WindFieldGenParamsDTO windParams, SimpleBusyIndicator busyIndicator, char mode, SimulatorMainPanel parent) { this.simulatorService = simulatorSvc; @@ -296,6 +297,7 @@ public class SimulatorMap extends AbsolutePanel implements RequiresDataInitializ this.errorReporter = errorReporter; this.xRes = xRes; this.yRes = yRes; + this.border = border; this.timer = timer; this.timePanel = null; timer.addTimeListener(this); @@ -316,13 +318,14 @@ public class SimulatorMap extends AbsolutePanel implements RequiresDataInitializ this.parent = parent; } - public SimulatorMap(SimulatorServiceAsync simulatorSvc, StringMessages stringMessages, ErrorReporter errorReporter, int xRes, int yRes, Timer timer, + public SimulatorMap(SimulatorServiceAsync simulatorSvc, StringMessages stringMessages, ErrorReporter errorReporter, int xRes, int yRes, int border, Timer timer, TimePanel timePanel, WindFieldGenParamsDTO windParams, SimpleBusyIndicator busyIndicator, char mode, SimulatorMainPanel parent) { this.simulatorService = simulatorSvc; this.stringMessages = stringMessages; this.errorReporter = errorReporter; this.xRes = xRes; this.yRes = yRes; + this.border = border; this.timer = timer; this.timePanel = timePanel; timer.addTimeListener(this); @@ -586,6 +589,7 @@ public class SimulatorMap extends AbsolutePanel implements RequiresDataInitializ windParams.setSouthEast(endPointDTO); windParams.setxRes(xRes); windParams.setyRes(yRes); + windParams.setBorder(border); busyIndicator.setBusy(true); timer.setTime(windParams.getStartTime().getTime()); @@ -703,6 +707,7 @@ public class SimulatorMap extends AbsolutePanel implements RequiresDataInitializ windParams.setxRes(xRes); windParams.setyRes(yRes); + windParams.setBorder(border); busyIndicator.setBusy(true); timer.setTime(windParams.getStartTime().getTime()); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/simulator/WindStreamletsCanvasOverlay.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/simulator/WindStreamletsCanvasOverlay.java index 9f284d75a3f..fdfee55c317 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/simulator/WindStreamletsCanvasOverlay.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/simulator/WindStreamletsCanvasOverlay.java @@ -159,15 +159,17 @@ public class WindStreamletsCanvasOverlay extends FullCanvasOverlay implements Ti public void extendWindDataJSON() { List data = this.windFieldDTO.getMatrix(); - int steps = data.size() / (this.windParams.getxRes() * this.windParams.getyRes()); String jsonData = "data:["; int p = 0; + int imax = this.windParams.getyRes() + 2*this.windParams.getBorderY(); + int jmax = this.windParams.getxRes() + 2*this.windParams.getBorderX(); + int steps = data.size() / (imax * jmax); double maxWindSpeed = 0; for(int s=0; s maxWindSpeed) { @@ -176,11 +178,11 @@ public class WindStreamletsCanvasOverlay extends FullCanvasOverlay implements Ti double y = wind.trueWindSpeedInKnots*Math.cos(wind.trueWindBearingDeg*Math.PI/180.0); double x = wind.trueWindSpeedInKnots*Math.sin(wind.trueWindBearingDeg*Math.PI/180.0); jsonData += x + "," + y; - if (j<(this.windParams.getxRes()-1)) { + if (j<(jmax-1)) { jsonData += ","; } } - if (i<(this.windParams.getyRes()-1)) { + if (i<(imax-1)) { jsonData += "],"; } else { jsonData += "]"; diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/simulator/util/ColorPaletteGenerator.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/simulator/util/ColorPaletteGenerator.java index 4b5b28c8204..f2c85b4dfd6 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/simulator/util/ColorPaletteGenerator.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/simulator/util/ColorPaletteGenerator.java @@ -3,7 +3,7 @@ package com.sap.sailing.gwt.ui.simulator.util; public class ColorPaletteGenerator implements ColorPalette { //private String[] colors = {"Green","Red","Blue","Yellow","Black"}; - private String[] colors = {"#00ED00","#FFBB00","#FFEA00","#0092C7","#0092C7","#666666","Blue","Blue","Yellow","Black"}; + private String[] colors = {"#00ED00","#FFBB00","#FFEA00","#0bf","#0bf","#808080","Blue","Blue","Yellow","Black"}; private int currentIndex = -1; public ColorPaletteGenerator() { diff --git a/java/com.sap.sailing.gwt.ui/wind-streamlets.js b/java/com.sap.sailing.gwt.ui/wind-streamlets.js index 4e2e7dd0b86..f7ebc5930f4 100644 --- a/java/com.sap.sailing.gwt.ui/wind-streamlets.js +++ b/java/com.sap.sailing.gwt.ui/wind-streamlets.js @@ -147,7 +147,9 @@ var VectorField = function(data) { this.rcEnd = data.rcEnd; this.resY = data.resY; this.resX = data.resX; - this.bdXi = 1.0 / 2.0 / (this.resY - 1); + this.borderY = data.borderY; + this.borderX = data.borderX; + this.bdXi = (data.borderY + 0.5) / (this.resY - 1); this.bdPhi = 1.0 + 2*this.bdXi; this.bdA = { lat:this.rcEnd.lat+(this.rcEnd.lat-this.rcStart.lat)*this.bdXi, lng:this.rcEnd.lng+(this.rcEnd.lng-this.rcStart.lng)*this.bdXi }; this.bdB = { lat:(this.rcStart.lat-this.rcEnd.lat)*this.bdPhi, lng:(this.rcStart.lng-this.rcEnd.lng)*this.bdPhi }; @@ -175,21 +177,26 @@ var VectorField = function(data) { var nrmLng = difLat/difLen; this.nvX = { lat: nrmLat/this.xScale/difLen*(this.resX-1), lng: nrmLng/this.xScale/difLen*(this.resX-1) }; this.gvX = { lat: nrmLat*this.xScale*difLen, lng: nrmLng/this.lngScale*this.xScale*difLen }; - + this.bdC = { lat:this.gvX.lat*(this.resX+2*this.borderX-1)/(this.resX-1), lng:this.gvX.lng*(this.resX+2*this.borderX-1)/(this.resX-1)}; }; VectorField.prototype.getRandomPosition = function() { var rndY = Math.random(); var rndX = Math.random() - 0.5; - var latP = this.bdA.lat + rndY * this.bdB.lat + rndX * this.gvX.lat; - var lngP = this.bdA.lng + rndY * this.bdB.lng + rndX * this.gvX.lng; + var latP = this.bdA.lat + rndY * this.bdB.lat + rndX * this.bdC.lat; + var lngP = this.bdA.lng + rndY * this.bdB.lng + rndX * this.bdC.lng; + + if (!this.inBounds(lngP, latP)) { + console.log("random-position: out of bounds"); + } + return {lat:latP, lng:lngP}; }; VectorField.prototype.inBounds = function(lng, lat) { var idx = this.getIndex(lat, lng); - var inBool = (idx.x >= 0) && (idx.x < this.resX) && (idx.y >= 0) && (idx.y < this.resY); + var inBool = (idx.x >= 0) && (idx.x < (this.resX+2*this.borderX)) && (idx.y >= 0) && (idx.y < (this.resY+2*this.borderY)); return inBool; }; @@ -198,7 +205,7 @@ VectorField.prototype.interpolate = function(lat, lng) { var idx = this.getNeighbors(lat, lng); var idxOff = 0; - if ((idx.xTop >= this.resX)||(idx.yTop >= this.resY)) { + if ((idx.xTop >= (this.resX+2*this.borderX))||(idx.yTop >= (this.resY+2*this.borderY))) { console.log("interpolate: out of range: " + idx.xTop + " " + idx.yTop); } @@ -215,7 +222,7 @@ VectorField.prototype.interpolate2 = function(lat, lng) { var idx = this.getNeighbors(lat, lng); var idxOff = 0; - if ((idx.xTop >= this.resX)||(idx.yTop >= this.resY)) { + if ((idx.xTop >= (this.resX+2*this.borderX))||(idx.yTop >= (this.resY+2*this.borderY))) { console.log("interpolate: out of range: " + idx.xTop + " " + idx.yTop); } @@ -281,8 +288,8 @@ VectorField.prototype.getIndex = function(lat, lng) { var posR = { lat: lat - this.rcStart.lat, lng: (lng - this.rcStart.lng) * this.lngScale }; // closest grid point - var yIdx = Math.round( posR.lat * this.nvY.lat + posR.lng * this.nvY.lng ); - var xIdx = Math.round( posR.lat * this.nvX.lat + posR.lng * this.nvX.lng + (this.resX - 1) / 2. ); + var yIdx = Math.round( posR.lat * this.nvY.lat + posR.lng * this.nvY.lng ) + this.borderY; + var xIdx = Math.round( posR.lat * this.nvX.lat + posR.lng * this.nvX.lng + (this.resX - 1) / 2. ) + this.borderX; return { x: xIdx, y: yIdx }; }; @@ -293,8 +300,8 @@ VectorField.prototype.getNeighbors = function(lat, lng) { var posR = { lat: lat - this.rcStart.lat, lng: (lng - this.rcStart.lng) * this.lngScale }; // surrounding grid points - var yFlt = posR.lat * this.nvY.lat + posR.lng * this.nvY.lng; - var xFlt = posR.lat * this.nvX.lat + posR.lng * this.nvX.lng + (this.resX - 1) / 2.; + var yFlt = posR.lat * this.nvY.lat + posR.lng * this.nvY.lng + this.borderY; + var xFlt = posR.lat * this.nvX.lat + posR.lng * this.nvX.lng + (this.resX - 1) / 2. + this.borderX; var yBot = Math.floor( yFlt ); var xBot = Math.floor( xFlt ); var yTop = Math.ceil( yFlt ); @@ -310,12 +317,12 @@ VectorField.prototype.getNeighbors = function(lat, lng) { yBot = 0; } - if (xTop >= this.resX) { - xTop = this.resX-1; + if (xTop >= (this.resX+2*this.borderX)) { + xTop = this.resX+2*this.borderX-1; } - if (yTop >= this.resY) { - yTop = this.resY-1; + if (yTop >= (this.resY+2*this.borderY)) { + yTop = this.resY+2*this.borderY-1; } return { xTop: xTop, yTop:yTop, xBot:xBot, yBot:yBot, xMod:xMod, yMod:yMod }; @@ -544,7 +551,7 @@ var Swarm = function(canvas, field, opt_projection) { this.background = 'rgb(' + this.rgb + ')'; var greyValue = 255; for (var i = 0; i < 256; i++) { - this.colors[i] = 'rgba(' + (greyValue) + ',' + (greyValue) + ',' + (greyValue) + ',' + (i/255) + ')'; + this.colors[i] = 'rgba(' + (greyValue) + ',' + (greyValue) + ',' + (greyValue) + ',' + (0.7*i/255.0) + ')'; //this.colors[i] = 'rgba(' + (255) + ',' + (255) + ',' + (255) + ',' + 1.0 + ')'; //this.colors[i] = 'hsla(' + 360*(0.55+0.9*(0.5-i/255)) + ',' + (100) + '% ,' + (50) + '%,' + (i/255) + ')'; } diff --git a/java/com.sap.sailing.simulator.test/src/com/sap/sailing/simulator/test/RectangularBoundaryTest.java b/java/com.sap.sailing.simulator.test/src/com/sap/sailing/simulator/test/RectangularBoundaryTest.java index 349b0ae10a4..09dc3634743 100644 --- a/java/com.sap.sailing.simulator.test/src/com/sap/sailing/simulator/test/RectangularBoundaryTest.java +++ b/java/com.sap.sailing.simulator.test/src/com/sap/sailing/simulator/test/RectangularBoundaryTest.java @@ -17,7 +17,7 @@ public class RectangularBoundaryTest { Position p2 = new DegreePosition(24.522137, -90.774536); Boundary b = new RectangularBoundary(p1, p2, 0.1); - Position[][] grid = b.extractGrid(20,20); + Position[][] grid = b.extractGrid(20,20,0,0); assertEquals("Number of lattice points",400,grid.length*grid[0].length); } diff --git a/java/com.sap.sailing.simulator.test/src/com/sap/sailing/simulator/test/SimulatorTest.java b/java/com.sap.sailing.simulator.test/src/com/sap/sailing/simulator/test/SimulatorTest.java index 96f709679f2..dc2a5a1ace5 100644 --- a/java/com.sap.sailing.simulator.test/src/com/sap/sailing/simulator/test/SimulatorTest.java +++ b/java/com.sap.sailing.simulator.test/src/com/sap/sailing/simulator/test/SimulatorTest.java @@ -42,7 +42,7 @@ public class SimulatorTest { PolarDiagram pd = new PolarDiagram49STG();//PolarDiagram49.CreateStandard49(); RectangularBoundary bd = new RectangularBoundary(start, end, 0.1); - Position[][] positions = bd.extractGrid(10, 10); + Position[][] positions = bd.extractGrid(10, 10, 0, 0); Bearing windBear = end.getBearingGreatCircle(start); WindControlParameters windParameters = new WindControlParameters(12.0, windBear.getDegrees()); WindFieldGenerator wf = new WindFieldGeneratorBlastImpl(bd, windParameters); diff --git a/java/com.sap.sailing.simulator.test/src/com/sap/sailing/simulator/test/TreeGrowTest.java b/java/com.sap.sailing.simulator.test/src/com/sap/sailing/simulator/test/TreeGrowTest.java index 41f6770949f..210645f98a2 100644 --- a/java/com.sap.sailing.simulator.test/src/com/sap/sailing/simulator/test/TreeGrowTest.java +++ b/java/com.sap.sailing.simulator.test/src/com/sap/sailing/simulator/test/TreeGrowTest.java @@ -43,7 +43,7 @@ public class TreeGrowTest { course.add(end); PolarDiagram pd = new PolarDiagram49STG();//PolarDiagram49.CreateStandard49(); RectangularBoundary bd = new RectangularBoundary(start, end, 0.1); - Position[][] positions = bd.extractGrid(10, 10); + Position[][] positions = bd.extractGrid(10, 10, 0, 0); //RectangularBoundary new_bd = new RectangularBoundary(start, end, 0.1); //Speed knotSpeed = new KnotSpeedImpl(8); WindControlParameters windParameters = new WindControlParameters(12, start.getBearingGreatCircle(end).reverse().getDegrees()); diff --git a/java/com.sap.sailing.simulator.test/src/com/sap/sailing/simulator/test/WindFieldGeneratorTest.java b/java/com.sap.sailing.simulator.test/src/com/sap/sailing/simulator/test/WindFieldGeneratorTest.java index d7b311955d9..fc415ac9122 100644 --- a/java/com.sap.sailing.simulator.test/src/com/sap/sailing/simulator/test/WindFieldGeneratorTest.java +++ b/java/com.sap.sailing.simulator.test/src/com/sap/sailing/simulator/test/WindFieldGeneratorTest.java @@ -53,7 +53,7 @@ public class WindFieldGeneratorTest { WindFieldGeneratorImpl wf = new WindFieldGeneratorBlastImpl(bd, windParameters); int hSteps = 10; int vSteps = 5; - Position[][] positions = bd.extractGrid(hSteps, vSteps); + Position[][] positions = bd.extractGrid(hSteps, vSteps, 0, 0); assert (positions.length*positions[0].length == hSteps * vSteps); int index = 0; for (int i = 0; i < positions.length; ++i) { @@ -61,7 +61,7 @@ public class WindFieldGeneratorTest { logger.info("P" + ++index + ":" + positions[i][j]); } } - wf.setPositionGrid(bd.extractGrid(hSteps, vSteps)); + wf.setPositionGrid(bd.extractGrid(hSteps, vSteps, 0, 0)); Position[][] positionGrid = wf.getPositionGrid(); assertNotNull("Position Grid is not null", positionGrid); assertEquals("Position Grid Number of Rows", vSteps, positionGrid.length); @@ -95,7 +95,7 @@ public class WindFieldGeneratorTest { int hSteps = 30; int vSteps = 15; - wf.setPositionGrid(bd.extractGrid(hSteps, vSteps)); + wf.setPositionGrid(bd.extractGrid(hSteps, vSteps, 0, 0)); Position[][] positionGrid = wf.getPositionGrid(); TimePoint startTime = new MillisecondsTimePoint(0); TimePoint timeStep = new MillisecondsTimePoint(30 * 1000); @@ -240,7 +240,7 @@ public class WindFieldGeneratorTest { int hSteps = 30; int vSteps = 15; - wf.setPositionGrid(bd.extractGrid(hSteps, vSteps)); + wf.setPositionGrid(bd.extractGrid(hSteps, vSteps, 0, 0)); Position[][] positionGrid = wf.getPositionGrid(); TimePoint startTime = new MillisecondsTimePoint(0); TimePoint timeStep = new MillisecondsTimePoint(30 * 1000); diff --git a/java/com.sap.sailing.simulator/src/com/sap/sailing/simulator/Boundary.java b/java/com.sap.sailing.simulator/src/com/sap/sailing/simulator/Boundary.java index b82e0c71f85..68f8aeacb80 100644 --- a/java/com.sap.sailing.simulator/src/com/sap/sailing/simulator/Boundary.java +++ b/java/com.sap.sailing.simulator/src/com/sap/sailing/simulator/Boundary.java @@ -23,10 +23,13 @@ public interface Boundary extends Serializable { boolean isWithinBoundaries(Position P); //List extractLattice(int hPoints, int vPoints); - Position[][] extractGrid(int hPoints, int vPoints); + Position[][] extractGrid(int hPoints, int vPoints, int borderY, int borderX); //List extractLattice(Distance hStep, Distance vstep); public Pair getGridIndex(Position x); - + + public int getResY(); + public int getResX(); + Bearing getNorth(); Bearing getSouth(); Bearing getEast(); diff --git a/java/com.sap.sailing.simulator/src/com/sap/sailing/simulator/impl/PathGeneratorDijkstra.java b/java/com.sap.sailing.simulator/src/com/sap/sailing/simulator/impl/PathGeneratorDijkstra.java index 78399cdc9d7..48ec11ee7e6 100644 --- a/java/com.sap.sailing.simulator/src/com/sap/sailing/simulator/impl/PathGeneratorDijkstra.java +++ b/java/com.sap.sailing.simulator/src/com/sap/sailing/simulator/impl/PathGeneratorDijkstra.java @@ -49,7 +49,7 @@ public class PathGeneratorDijkstra extends PathGeneratorBase { int gridv = this.parameters.getProperty("Djikstra.gridv[int]").intValue(); // number of vertical grid steps int gridh = this.parameters.getProperty("Djikstra.gridh[int]").intValue(); // number of horizontal grid // steps - Position[][] sailGrid = boundary.extractGrid(gridh, gridv); + Position[][] sailGrid = boundary.extractGrid(gridh, gridv, 0, 0); // create adjacency graph including start and end Map> graph = new HashMap>(); diff --git a/java/com.sap.sailing.simulator/src/com/sap/sailing/simulator/impl/PathGeneratorDynProgForward.java b/java/com.sap.sailing.simulator/src/com/sap/sailing/simulator/impl/PathGeneratorDynProgForward.java index 593156e650f..f633e2dbe33 100644 --- a/java/com.sap.sailing.simulator/src/com/sap/sailing/simulator/impl/PathGeneratorDynProgForward.java +++ b/java/com.sap.sailing.simulator/src/com/sap/sailing/simulator/impl/PathGeneratorDynProgForward.java @@ -162,7 +162,7 @@ public class PathGeneratorDynProgForward extends PathGeneratorBase { } // generate grid positions using sgridh and sgridv - Position[][] sailGrid = boundary.extractGrid(spatialGridsizeHorizontal, spatialGridsizeVertical); + Position[][] sailGrid = boundary.extractGrid(spatialGridsizeHorizontal, spatialGridsizeVertical, 0, 0); // optimization grid indexes: // vertical steps: 0, ..., v-1 diff --git a/java/com.sap.sailing.simulator/src/com/sap/sailing/simulator/impl/RectangularBoundary.java b/java/com.sap.sailing.simulator/src/com/sap/sailing/simulator/impl/RectangularBoundary.java index dbab28d0be4..b69a3e2e418 100644 --- a/java/com.sap.sailing.simulator/src/com/sap/sailing/simulator/impl/RectangularBoundary.java +++ b/java/com.sap.sailing.simulator/src/com/sap/sailing/simulator/impl/RectangularBoundary.java @@ -20,6 +20,8 @@ public class RectangularBoundary implements Boundary { private double[] nvHor; // horizontal normal vector with suitable length private int vPoints; // number of vertical steps private int hPoints; // number of horizontal steps + private int borderY; + private int borderX; private Position northWest; //private Position southEast; @@ -129,11 +131,14 @@ public class RectangularBoundary implements Boundary { } @Override - public Position[][] extractGrid(int hPoints, int vPoints) { + public Position[][] extractGrid(int hPoints, int vPoints, int borderY, int borderX) { this.vPoints = vPoints; this.hPoints = hPoints; + this.borderY = borderY; + this.borderX = borderX; + double xscale = 1.5; double alat = (rcEnd.getLatDeg() + rcStart.getLatDeg()) / 2.; @@ -166,9 +171,9 @@ public class RectangularBoundary implements Boundary { nHor[1] = nscHor[1] / lngScale; // System.out.println("LngScale:"+lngScale+", Diff.Vrt:"+dVrt); - Position[][] grid = new Position[vPoints][hPoints]; + Position[][] grid = new Position[vPoints+2*borderY][hPoints+2*borderX]; Position pv; - for (int i = 0; i < vPoints; i++) { + for (int i = -borderY; i < (vPoints+borderY); i++) { // System.out.print("nrow "+i+": "); if (i == 0) { @@ -182,25 +187,25 @@ public class RectangularBoundary implements Boundary { int j = 0; // left side - while (j < hPoints / 2) { - grid[i][j] = new DegreePosition(pv.getLatDeg() - ((hPoints - 1) / 2. - j) / (hPoints - 1) * nHor[0] - * xscale * lscVrt, pv.getLngDeg() - ((hPoints - 1) / 2. - j) / (hPoints - 1) * nHor[1] * xscale + while (j < (hPoints+2*borderX) / 2) { + grid[i+borderY][j] = new DegreePosition(pv.getLatDeg() - ((hPoints + 2*borderX - 1) / 2. - j) / (hPoints - 1) * nHor[0] + * xscale * lscVrt, pv.getLngDeg() - ((hPoints + 2*borderX - 1) / 2. - j) / (hPoints - 1) * nHor[1] * xscale * lscVrt); // System.out.print(""+grid[i][j]+"("+((hPoints-1)/2.-j)+"), "); j++; } // middle - if (hPoints % 2 == 1) { - grid[i][j] = pv; + if ((hPoints+2*borderX) % 2 == 1) { + grid[i+borderY][j] = pv; // System.out.print(""+grid[i][j]+", "); j++; } // right side - while (j < hPoints) { - grid[i][j] = new DegreePosition(pv.getLatDeg() + (j - (hPoints - 1) / 2.) / (hPoints - 1) * nHor[0] - * xscale * lscVrt, pv.getLngDeg() + (j - (hPoints - 1) / 2.) / (hPoints - 1) * nHor[1] * xscale + while (j < (hPoints+2*borderX)) { + grid[i+borderY][j] = new DegreePosition(pv.getLatDeg() + (j - (hPoints + 2*borderX - 1) / 2.) / (hPoints - 1) * nHor[0] + * xscale * lscVrt, pv.getLngDeg() + (j - (hPoints + 2*borderX - 1) / 2.) / (hPoints - 1) * nHor[1] * xscale * lscVrt); // System.out.print(""+grid[i][j]+"("+(j-(hPoints-1)/2.)+"), "); j++; @@ -224,8 +229,8 @@ public class RectangularBoundary implements Boundary { double sPrd = scX[0] * nvHor[0] + scX[1] * nvHor[1]; - int vIdx = Math.min(Math.max(0, (int) Math.round(scX[0] * nvVrt[0] + scX[1] * nvVrt[1])), vPoints - 1); - int hIdx = Math.min(Math.max(0, (int) Math.round(sPrd + (hPoints - 1) / 2.)), hPoints - 1); + int vIdx = Math.min(Math.max(-this.borderY, (int) Math.round(scX[0] * nvVrt[0] + scX[1] * nvVrt[1])), vPoints - 1 + this.borderY); + int hIdx = Math.min(Math.max(-this.borderX, (int) Math.round(sPrd + (hPoints - 1) / 2.)), hPoints - 1 + this.borderX); // System.out.println("getGridIndex: "+vIdx+","+hIdx+"("+vPoints+","+hPoints+")"); return new Pair(vIdx, hIdx); @@ -262,6 +267,16 @@ public class RectangularBoundary implements Boundary { * return lst; } */ + @Override + public int getResY() { + return this.vPoints; + } + + @Override + public int getResX() { + return this.hPoints; + } + @Override public Bearing getNorth() { return north; diff --git a/java/com.sap.sailing.simulator/src/com/sap/sailing/simulator/impl/SailingSimulatorImpl.java b/java/com.sap.sailing.simulator/src/com/sap/sailing/simulator/impl/SailingSimulatorImpl.java index 169d97e565b..b2a7dd2be1f 100644 --- a/java/com.sap.sailing.simulator/src/com/sap/sailing/simulator/impl/SailingSimulatorImpl.java +++ b/java/com.sap.sailing.simulator/src/com/sap/sailing/simulator/impl/SailingSimulatorImpl.java @@ -103,7 +103,7 @@ public class SailingSimulatorImpl implements SailingSimulator { } wf.setBoundary(bd); - Position[][] positionGrid = bd.extractGrid(gridRes[0], gridRes[1]); + Position[][] positionGrid = bd.extractGrid(gridRes[0], gridRes[1], gridRes[2], gridRes[3]); wf.setPositionGrid(positionGrid); wf.generate(wf.getStartTime(), wf.getEndTime(), wf.getTimeStep()); } diff --git a/java/com.sap.sailing.simulator/src/com/sap/sailing/simulator/windfield/impl/WindFieldGeneratorOscillationImpl.java b/java/com.sap.sailing.simulator/src/com/sap/sailing/simulator/windfield/impl/WindFieldGeneratorOscillationImpl.java index c83ff403878..744d0443593 100644 --- a/java/com.sap.sailing.simulator/src/com/sap/sailing/simulator/windfield/impl/WindFieldGeneratorOscillationImpl.java +++ b/java/com.sap.sailing.simulator/src/com/sap/sailing/simulator/windfield/impl/WindFieldGeneratorOscillationImpl.java @@ -41,7 +41,7 @@ public class WindFieldGeneratorOscillationImpl extends WindFieldGeneratorImpl im if (positions == null || positions.length < 1) { return; } - int vPoints = positions.length; + int vPoints = this.boundary.getResY(); Distance vStep = boundary.getHeight().scale(1.0/(vPoints-1)); if (windParameters.baseWindSpeed > 0) { timeScale = vStep.getNauticalMiles()/windParameters.baseWindSpeed; @@ -56,7 +56,7 @@ public class WindFieldGeneratorOscillationImpl extends WindFieldGeneratorImpl im return; } - int ncol = positions[0].length; + int ncol = boundary.getResX(); speed = new Speed[ncol]; double leftSpeed = windParameters.baseWindSpeed*windParameters.leftWindSpeed/100.0; @@ -85,6 +85,12 @@ public class WindFieldGeneratorOscillationImpl extends WindFieldGeneratorImpl im Pair positionIndex = getPositionIndex(p); if (positionIndex != null) { int colIndex = positionIndex.getB(); + if (colIndex < 0) { + colIndex = 0; + } + if (colIndex >= this.boundary.getResX()) { + colIndex = this.boundary.getResX()-1; + } return speed[colIndex]; } else { logger.severe("Error finding position " + p);