From d8a2f27cc423c180bc8fe0a774e97d2c08a27719 Mon Sep 17 00:00:00 2001 From: Kenneth VanderLinde Date: Thu, 11 Apr 2024 20:51:05 -0700 Subject: [PATCH 1/3] Add copy constructors to CellPoint and ZonePoint --- src/main/java/net/rptools/maptool/model/CellPoint.java | 4 ++++ src/main/java/net/rptools/maptool/model/ZonePoint.java | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/main/java/net/rptools/maptool/model/CellPoint.java b/src/main/java/net/rptools/maptool/model/CellPoint.java index a49c2710df..cfdcdf1f86 100644 --- a/src/main/java/net/rptools/maptool/model/CellPoint.java +++ b/src/main/java/net/rptools/maptool/model/CellPoint.java @@ -43,6 +43,10 @@ public CellPoint(int x, int y, double distanceTraveled, double distanceTraveledW this.distanceTraveledWithoutTerrain = distanceTraveledWithoutTerrain; } + public CellPoint(CellPoint other) { + this(other.x, other.y); + } + @Override public String toString() { return "CellPoint" + super.toString(); diff --git a/src/main/java/net/rptools/maptool/model/ZonePoint.java b/src/main/java/net/rptools/maptool/model/ZonePoint.java index 2e79710d82..3b89a26244 100644 --- a/src/main/java/net/rptools/maptool/model/ZonePoint.java +++ b/src/main/java/net/rptools/maptool/model/ZonePoint.java @@ -19,6 +19,10 @@ public ZonePoint(int x, int y) { super(x, y); } + public ZonePoint(ZonePoint other) { + this(other.x, other.y); + } + @Override public String toString() { return "ZonePoint" + super.toString(); From 9eda357217d5d4f0ee9db674cbaa2afa9297f47d Mon Sep 17 00:00:00 2001 From: Kenneth VanderLinde Date: Thu, 11 Apr 2024 12:40:48 -0700 Subject: [PATCH 2/3] Remove unused mouse slope state from LineCellTemplate --- .../tool/drawing/LineCellTemplateTool.java | 20 ---------------- .../maptool/model/drawing/Drawable.java | 1 - .../model/drawing/LineCellTemplate.java | 24 +------------------ src/main/proto/drawing_dto.proto | 5 ++-- 4 files changed, 3 insertions(+), 47 deletions(-) diff --git a/src/main/java/net/rptools/maptool/client/tool/drawing/LineCellTemplateTool.java b/src/main/java/net/rptools/maptool/client/tool/drawing/LineCellTemplateTool.java index 3223c5f634..409317a03c 100644 --- a/src/main/java/net/rptools/maptool/client/tool/drawing/LineCellTemplateTool.java +++ b/src/main/java/net/rptools/maptool/client/tool/drawing/LineCellTemplateTool.java @@ -196,26 +196,6 @@ protected void handleMouseMovement(MouseEvent e) { } // endif if (setCellAtMouse(e, pathVertex)) lt.clearPath(); - // Determine which of the extra squares are used on diagonals - double dx = pathVertex.x - vertex.x; - double dy = pathVertex.y - vertex.y; - if (dx != 0 && dy != 0) { // Ignore straight lines - boolean mouseSlopeGreater = false; - double m = Math.abs(dy / dx); - double edx = e.getX() - vertex.x; - double edy = e.getY() - vertex.y; - if (edx != 0 && edy != 0) { // Handle straight lines differently - double em = Math.abs(edy / edx); - mouseSlopeGreater = em > m; - } else if (edx == 0) { - mouseSlopeGreater = true; - } // endif - if (mouseSlopeGreater != lt.isMouseSlopeGreater()) { - lt.setMouseSlopeGreater(mouseSlopeGreater); - renderer.repaint(); - } // endif - } // endif - // Let control move the path anchor } else if (SwingUtil.isControlDown(e)) { handleControlOffset(e, pathVertex); diff --git a/src/main/java/net/rptools/maptool/model/drawing/Drawable.java b/src/main/java/net/rptools/maptool/model/drawing/Drawable.java index 2b10791b15..2752174b26 100644 --- a/src/main/java/net/rptools/maptool/model/drawing/Drawable.java +++ b/src/main/java/net/rptools/maptool/model/drawing/Drawable.java @@ -144,7 +144,6 @@ static Drawable fromDto(DrawableDto drawableDto) { if (!dto.getQuadrant().isEmpty()) { drawable.setQuadrant(AbstractTemplate.Quadrant.valueOf(dto.getQuadrant())); } - drawable.setMouseSlopeGreater(dto.getMouseSlopeGreater()); var pathVertex = dto.getPathVertex(); drawable.setPathVertex(new ZonePoint(pathVertex.getX(), pathVertex.getY())); if (dto.hasName()) { diff --git a/src/main/java/net/rptools/maptool/model/drawing/LineCellTemplate.java b/src/main/java/net/rptools/maptool/model/drawing/LineCellTemplate.java index 1a5a5f87c7..8d6bb1be04 100644 --- a/src/main/java/net/rptools/maptool/model/drawing/LineCellTemplate.java +++ b/src/main/java/net/rptools/maptool/model/drawing/LineCellTemplate.java @@ -57,9 +57,6 @@ public class LineCellTemplate extends AbstractTemplate { */ private String quadrant = null; - /** Flag used to determine mouse position relative to vertex position */ - private boolean mouseSlopeGreater; - public LineCellTemplate() {} public LineCellTemplate(GUID id) { @@ -356,24 +353,6 @@ public void setQuadrant(Quadrant quadrant) { } } - /** - * Get the mouseSlopeGreater for this LineTemplate. - * - * @return Returns the current value of mouseSlopeGreater. - */ - public boolean isMouseSlopeGreater() { - return mouseSlopeGreater; - } - - /** - * Set the value of mouseSlopeGreater for this LineTemplate. - * - * @param aMouseSlopeGreater The mouseSlopeGreater to set. - */ - public void setMouseSlopeGreater(boolean aMouseSlopeGreater) { - mouseSlopeGreater = aMouseSlopeGreater; - } - /** * @return Getter for path */ @@ -504,8 +483,7 @@ public DrawableDto toDto() { .setLayer(getLayer().name()) .setZoneId(getZoneId().toString()) .setRadius(getRadius()) - .setVertex(getVertex().toDto()) - .setMouseSlopeGreater(isMouseSlopeGreater()); + .setVertex(getVertex().toDto()); if (getQuadrant() != null) { dto.setQuadrant(getQuadrant().name()); diff --git a/src/main/proto/drawing_dto.proto b/src/main/proto/drawing_dto.proto index 98e45786bd..b0bf6997bf 100644 --- a/src/main/proto/drawing_dto.proto +++ b/src/main/proto/drawing_dto.proto @@ -126,9 +126,8 @@ message LineCellTemplateDto { string zoneId = 4; IntPointDto vertex = 5; int32 radius = 6; - bool mouse_slope_greater = 7; - string quadrant = 8; - IntPointDto path_vertex = 9; + string quadrant = 7; + IntPointDto path_vertex = 8; } message RadiusCellTemplateDto { From 6de6d88195b8bcdeef735f229311e2e31bf07bb9 Mon Sep 17 00:00:00 2001 From: Kenneth VanderLinde Date: Thu, 11 Apr 2024 12:02:47 -0700 Subject: [PATCH 3/3] Rework LineCellTemplate path and bounds `calcPath()` has been simplified to essentially Bressenham's algorithm. It only calculates and returns a path, while `getPath()` (previously unused) will call it if needed. `getBounds()` now correctly accounts for the path's quadrant and the position of the first vertex to produce a correctly located and sized bounding box. This method was also simplified to only look at the two endpoints rather than iterating over the entire line. All fields except `pathVertex` are now marked as `transient` since they can be recovered from only `getVertex()` and `pathVertex`. Correspondingly, the quadrant is not longer part of the DTO, and the serialized XML is much smaller. With the above changes in, it was natural to simplify `LineCellTemplateTool` to avoid a lot of case work, especially in not relying on mutations of `getPathVertex()`. --- .../tool/drawing/LineCellTemplateTool.java | 30 +- .../maptool/model/drawing/Drawable.java | 3 - .../model/drawing/LineCellTemplate.java | 355 ++++++++---------- src/main/proto/drawing_dto.proto | 3 +- 4 files changed, 171 insertions(+), 220 deletions(-) diff --git a/src/main/java/net/rptools/maptool/client/tool/drawing/LineCellTemplateTool.java b/src/main/java/net/rptools/maptool/client/tool/drawing/LineCellTemplateTool.java index 409317a03c..0e085f6eea 100644 --- a/src/main/java/net/rptools/maptool/client/tool/drawing/LineCellTemplateTool.java +++ b/src/main/java/net/rptools/maptool/client/tool/drawing/LineCellTemplateTool.java @@ -19,13 +19,11 @@ import java.awt.event.MouseEvent; import java.awt.geom.AffineTransform; import javax.swing.SwingUtilities; -import net.rptools.maptool.client.ScreenPoint; import net.rptools.maptool.client.swing.SwingUtil; import net.rptools.maptool.client.tool.Tool; import net.rptools.maptool.client.ui.zone.renderer.ZoneRenderer; import net.rptools.maptool.model.ZonePoint; import net.rptools.maptool.model.drawing.AbstractTemplate; -import net.rptools.maptool.model.drawing.AbstractTemplate.Quadrant; import net.rptools.maptool.model.drawing.LineCellTemplate; import net.rptools.maptool.model.drawing.Pen; @@ -173,7 +171,6 @@ public void mousePressed(MouseEvent aE) { protected void handleMouseMovement(MouseEvent e) { // Setting anchor point? LineCellTemplate lt = (LineCellTemplate) template; - ZonePoint pathVertex = lt.getPathVertex(); ZonePoint vertex = lt.getVertex(); if (!anchorSet) { @@ -189,38 +186,21 @@ protected void handleMouseMovement(MouseEvent e) { template.setRadius(getRadiusAtMouse(e)); controlOffset = null; - // The path vertex remains null until it is set the first time. - if (pathVertex == null) { - pathVertex = new ZonePoint(vertex.x, vertex.y); - lt.setPathVertex(pathVertex); - } // endif - if (setCellAtMouse(e, pathVertex)) lt.clearPath(); + ZonePoint pathVertex = getCellAtMouse(e); + lt.setPathVertex(pathVertex); + renderer.repaint(); // Let control move the path anchor } else if (SwingUtil.isControlDown(e)) { + ZonePoint pathVertex = lt.getPathVertex(); handleControlOffset(e, pathVertex); + lt.setPathVertex(pathVertex); // Set the final radius } else { template.setRadius(getRadiusAtMouse(e)); renderer.repaint(); controlOffset = null; - return; - } // endif - - // Quadrant change? - if (pathVertex != null) { - ZonePoint mouse = new ScreenPoint(e.getX(), e.getY()).convertToZone(renderer); - int dx = mouse.x - vertex.x; - int dy = mouse.y - vertex.y; - AbstractTemplate.Quadrant quadrant = - (dx < 0) - ? (dy < 0 ? Quadrant.NORTH_WEST : Quadrant.SOUTH_WEST) - : (dy < 0 ? Quadrant.NORTH_EAST : Quadrant.SOUTH_EAST); - if (quadrant != lt.getQuadrant()) { - lt.setQuadrant(quadrant); - renderer.repaint(); - } // endif } // endif } } diff --git a/src/main/java/net/rptools/maptool/model/drawing/Drawable.java b/src/main/java/net/rptools/maptool/model/drawing/Drawable.java index 2752174b26..4bbf965be3 100644 --- a/src/main/java/net/rptools/maptool/model/drawing/Drawable.java +++ b/src/main/java/net/rptools/maptool/model/drawing/Drawable.java @@ -141,9 +141,6 @@ static Drawable fromDto(DrawableDto drawableDto) { drawable.setRadius(dto.getRadius()); var vertex = dto.getVertex(); drawable.setVertex(new ZonePoint(vertex.getX(), vertex.getY())); - if (!dto.getQuadrant().isEmpty()) { - drawable.setQuadrant(AbstractTemplate.Quadrant.valueOf(dto.getQuadrant())); - } var pathVertex = dto.getPathVertex(); drawable.setPathVertex(new ZonePoint(pathVertex.getX(), pathVertex.getY())); if (dto.hasName()) { diff --git a/src/main/java/net/rptools/maptool/model/drawing/LineCellTemplate.java b/src/main/java/net/rptools/maptool/model/drawing/LineCellTemplate.java index 8d6bb1be04..f5b22f20b8 100644 --- a/src/main/java/net/rptools/maptool/model/drawing/LineCellTemplate.java +++ b/src/main/java/net/rptools/maptool/model/drawing/LineCellTemplate.java @@ -18,12 +18,11 @@ import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.geom.Area; -import java.math.BigDecimal; -import java.math.MathContext; -import java.math.RoundingMode; import java.util.ArrayList; import java.util.List; import java.util.ListIterator; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; import net.rptools.maptool.client.MapTool; import net.rptools.maptool.model.CellPoint; import net.rptools.maptool.model.GUID; @@ -43,19 +42,16 @@ public class LineCellTemplate extends AbstractTemplate { *-------------------------------------------------------------------------------------------*/ /** This vertex is used to determine the path. */ - private ZonePoint pathVertex; + private ZonePoint pathVertex = null; /** The calculated path for this line. */ - private List path; + private transient List path; /** The pool of points. */ - private List pool; + private transient List pool; - /** - * The line is drawn in this quadrant. A string is used as a hack to get around the hessian - * library's problem w/ serialization of enums - */ - private String quadrant = null; + /** The line is drawn in this quadrant. */ + private transient Quadrant quadrant = null; public LineCellTemplate() {} @@ -89,8 +85,15 @@ protected void paintBorder( // Have to scan 3 points behind and ahead, since that is the maximum number of points // that can be added to the path from any single intersection. boolean[] noPaint = new boolean[4]; + final var path = getPath(); + if (path == null) { + return; + } + for (int i = pElement - 3; i < pElement + 3; i++) { - if (i < 0 || i >= path.size() || i == pElement) continue; + if (i < 0 || i >= path.size() || i == pElement) { + continue; + } CellPoint p = path.get(i); // Ignore diagonal cells and cells that are not adjacent @@ -125,7 +128,8 @@ protected void paint(Graphics2D g, boolean border, boolean area) { if (getRadius() == 0) { return; } - if (calcPath() == null) { + final var path = getPath(); + if (path == null) { return; } @@ -138,13 +142,20 @@ protected void paint(Graphics2D g, boolean border, boolean area) { int yOff = p.y * gridSize; int distance = getDistance(p.x, p.y); - if (quadrant.equals(Quadrant.NORTH_EAST.name())) { - yOff = yOff - gridSize; - } else if (quadrant.equals(Quadrant.SOUTH_WEST.name())) { - xOff = xOff - gridSize; - } else if (quadrant.equals(Quadrant.NORTH_WEST.name())) { - xOff = xOff - gridSize; - yOff = yOff - gridSize; + switch (getQuadrant()) { + case NORTH_EAST -> { + yOff = yOff - gridSize; + } + case SOUTH_WEST -> { + xOff = xOff - gridSize; + } + case NORTH_WEST -> { + xOff = xOff - gridSize; + yOff = yOff - gridSize; + } + case SOUTH_EAST -> { + // Nothing to do. + } } // Paint what is needed. @@ -185,86 +196,70 @@ public void setRadius(int squares) { /** * Calculate the path * + *

The path is always calculated as if it were in the south-east quadrant. I.e., the x and y + * coordinates of the path points will never decrease. + * * @return The new path or null if there is no path. */ - protected List calcPath() { - if (getRadius() == 0) { - return null; - } - if (pathVertex == null) { - return null; - } + protected @Nullable List calcPath() { int radius = getRadius(); + ZonePoint vertex = getVertex(); + if (radius == 0 || vertex == null || pathVertex == null) { + return null; + } // Is there a slope? - ZonePoint vertex = getVertex(); if (vertex.equals(pathVertex)) { return null; } - double dx = pathVertex.x - vertex.x; - double dy = pathVertex.y - vertex.y; - setQuadrant( - (dx < 0) - ? (dy < 0 ? Quadrant.NORTH_WEST : Quadrant.SOUTH_WEST) - : (dy < 0 ? Quadrant.NORTH_EAST : Quadrant.SOUTH_EAST)); + double dx = Math.abs(pathVertex.x - vertex.x); + double dy = Math.abs(pathVertex.y - vertex.y); + final boolean isShallowSlope = dx >= dy; + // To start, a half cell deviation is enough to switch rows. + double deviationInY = 0.5; + + final var path = new ArrayList(); // Start the line at 0,0 - clearPath(); - path = new ArrayList(); - path.add(getPointFromPool(0, 0)); - - MathContext mc = MathContext.DECIMAL128; - MathContext rmc = new MathContext(MathContext.DECIMAL64.getPrecision(), RoundingMode.CEILING); - if (dx != 0 && dy != 0) { - BigDecimal m = BigDecimal.valueOf(dy).divide(BigDecimal.valueOf(dx), mc).abs(); - - // Find the path - CellPoint p = path.get(path.size() - 1); - while (getDistance(p.x, p.y) < radius) { - int x = p.x; - int y = p.y; - - // Which border does the point exit the cell? - double xValue = BigDecimal.valueOf(y + 1).divide(m, mc).round(rmc).doubleValue(); - double yValue = BigDecimal.valueOf(x + 1).multiply(m, mc).round(rmc).doubleValue(); - - if (xValue == x + 1 && yValue == y + 1) { - // Special case, right on the diagonal - path.add(getPointFromPool(x + 1, y + 1)); - } else if (Math.round(xValue) == x + 1) { - path.add(getPointFromPool(x + 1, y + 1)); - } else if (Math.round(xValue) == x) { - path.add(getPointFromPool(x, y + 1)); - } else if (Math.round(yValue) == y + 1) { - path.add(getPointFromPool(x + 1, y + 1)); - } else if (Math.round(yValue) == y) { - path.add(getPointFromPool(x + 1, y)); - } else { - return path; - } // endif - p = path.get(path.size() - 1); - } // endwhile - - // Clear the last of the pool - if (pool != null) { - pool.clear(); - pool = null; - } // endif - } else { - // Straight line - int xInc = dx != 0 ? 1 : 0; - int yInc = dy != 0 ? 1 : 0; - int x = xInc; - int y = yInc; - int xTouch = (dx != 0) ? 0 : -1; - int yTouch = (dy != 0) ? 0 : -1; - while (getDistance(x, y) <= radius) { - path.add(getPointFromPool(x, y)); - x += xInc; - y += yInc; - } // endwhile - } // endif + CellPoint p = getPointFromPool(0, 0); + path.add(p); + + // In this loop we pretend we have a shallow slope. If that's not true, we'll fix it afterward. + double slope = isShallowSlope ? (dy / dx) : (dx / dy); + assert slope >= 0; + while (getDistance(p.x, p.y) < radius) { + p = getPointFromPool(p.x, p.y); + + // Step to the next column. + ++p.x; + + // Step to the next row if the ideal line has deviated enough. + // y-value always goes up, so we don't need to check the < 0 case. + deviationInY += slope; + if (deviationInY >= 1) { + ++p.y; + deviationInY -= 1; + } + + path.add(p); + } + + if (!isShallowSlope) { + // All our x-values should be y-values and vice versa. So swap them all. + for (final var point : path) { + final var tmp = point.x; + point.x = point.y; + point.y = tmp; + } + } + + // Clear out the last of the pool. + if (pool != null) { + pool.clear(); + pool = null; + } + return path; } @@ -275,7 +270,7 @@ protected List calcPath() { * @param y The y coordinate of the new point. * @return The new point. */ - public CellPoint getPointFromPool(int x, int y) { + private CellPoint getPointFromPool(int x, int y) { CellPoint p = null; if (pool != null) { p = pool.remove(pool.size() - 1); @@ -289,22 +284,13 @@ public CellPoint getPointFromPool(int x, int y) { return p; } - /** - * Add a point back to the pool. - * - * @param p Add this point back - */ - public void addPointToPool(CellPoint p) { - if (pool != null) pool.add(p); - } - /** * Get the pathVertex for this LineTemplate. * * @return Returns the current value of pathVertex. */ public ZonePoint getPathVertex() { - return pathVertex; + return pathVertex == null ? null : new ZonePoint(pathVertex); } /** @@ -321,7 +307,8 @@ public void setPathVertex(ZonePoint pathVertex) { } /** Clear the current path. This will cause it to be recalculated during the next draw. */ - public void clearPath() { + private void clearPath() { + quadrant = null; if (path != null) { pool = path; } @@ -333,38 +320,34 @@ public void clearPath() { * * @return Returns the current value of quadrant. */ - public Quadrant getQuadrant() { - if (quadrant != null) { - return Quadrant.valueOf(quadrant); + private @Nonnull Quadrant getQuadrant() { + if (quadrant == null) { + final var vertex = getVertex(); + if (vertex == null || pathVertex == null || pathVertex.equals(vertex)) { + // Not a valid line, so quadrant is meaningless. Just pick one. + quadrant = Quadrant.NORTH_WEST; + } else { + double dx = pathVertex.x - vertex.x; + double dy = pathVertex.y - vertex.y; + quadrant = + (dx < 0) + ? (dy < 0 ? Quadrant.NORTH_WEST : Quadrant.SOUTH_WEST) + : (dy < 0 ? Quadrant.NORTH_EAST : Quadrant.SOUTH_EAST); + } } - return null; - } - /** - * Set the value of quadrant for this LineTemplate. - * - * @param quadrant The quadrant to set. - */ - public void setQuadrant(Quadrant quadrant) { - if (quadrant != null) { - this.quadrant = quadrant.name(); - } else { - this.quadrant = null; - } + return quadrant; } /** * @return Getter for path */ - public List getPath() { - return path; - } + private @Nullable List getPath() { + if (path == null) { + path = calcPath(); + } - /** - * @param path Setter for the path to set - */ - public void setPath(List path) { - this.path = path; + return path; } /*--------------------------------------------------------------------------------------------- @@ -376,70 +359,63 @@ public void setPath(List path) { */ public Rectangle getBounds() { // Get all of the numbers needed for the calculation - if (MapTool.getCampaign().getZone(getZoneId()) == null) { + final var zone = MapTool.getCampaign().getZone(getZoneId()); + if (zone == null) { return new Rectangle(); } - int gridSize = MapTool.getCampaign().getZone(getZoneId()).getGrid().getSize(); - ZonePoint vertex = getVertex(); - - // Find the point that is farthest away in the path, then adjust - ZonePoint minp = null; - ZonePoint maxp = null; + // The end of the path is the point further away from vertex. + final var path = getPath(); if (path == null) { - calcPath(); - if (path == null) { - // If the calculated path is still null, then the line is invalid. - return new Rectangle(); - } + // If the path is null, the line is invalid. + return new Rectangle(); } - for (CellPoint pt : path) { - ZonePoint p = MapTool.getCampaign().getZone(getZoneId()).getGrid().convert(pt); - p = new ZonePoint(vertex.x + p.x, vertex.y + p.y); - if (minp == null) { - minp = new ZonePoint(p.x, p.y); - maxp = new ZonePoint(p.x, p.y); - } - minp.x = Math.min(minp.x, p.x); - minp.y = Math.min(minp.y, p.y); + var first = new CellPoint(path.getFirst()); + var last = new CellPoint(path.getLast()); - maxp.x = Math.max(maxp.x, p.x); - maxp.y = Math.max(maxp.y, p.y); - } - maxp.x += gridSize; - maxp.y += gridSize; - - // The path is only calculated for the south-east quadrant, so - // appropriately reflect the bounding box around the starting vertex. - if (getXMult(getQuadrant()) < 0) { - minp.x -= gridSize; - maxp.x -= gridSize; - } - if (getYMult(getQuadrant()) < 0) { - minp.y -= gridSize; - maxp.y -= gridSize; - } - int width = (maxp.x - minp.x); - int height = (maxp.y - minp.y); + // `first` should be (0, 0), but let's not rely on that. + final var quadrant = getQuadrant(); + first.x *= getXMult(quadrant); + last.x *= getXMult(quadrant); + first.y *= getYMult(quadrant); + last.y *= getYMult(quadrant); + + // Now convert to zone points. + ZonePoint firstZonePoint = zone.getGrid().convert(first); + ZonePoint lastZonePoint = zone.getGrid().convert(last); + + ZonePoint vertex = getVertex(); + int gridSize = zone.getGrid().getSize(); + ZonePoint minZonePoint = + new ZonePoint( + vertex.x + Math.min(firstZonePoint.x, lastZonePoint.x), + vertex.y + Math.min(firstZonePoint.y, lastZonePoint.y)); + ZonePoint maxZonePoint = + new ZonePoint( + vertex.x + Math.max(firstZonePoint.x, lastZonePoint.x) + gridSize, + vertex.y + Math.max(firstZonePoint.y, lastZonePoint.y) + gridSize); // Account for pen size // We don't really know what the pen size will be, so give a very rough // overestimate // We'll have to figure this out someday - minp.x -= 10; - minp.y -= 10; - width += 20; - height += 20; - - return new Rectangle(minp.x, minp.y, width, height); + minZonePoint.x -= 10; + minZonePoint.y -= 10; + maxZonePoint.x += 10; + maxZonePoint.y += 10; + + return new Rectangle( + minZonePoint.x, + minZonePoint.y, + maxZonePoint.x - minZonePoint.x, + maxZonePoint.y - minZonePoint.y); } @Override public Area getArea() { - if (path == null) { - calcPath(); - } Zone zone = MapTool.getCampaign().getZone(getZoneId()); + + final var path = getPath(); if (path == null || zone == null || getRadius() == 0 || pathVertex == null) { return new Area(); } @@ -455,13 +431,20 @@ public Area getArea() { int xOff = p.x * gridSize; int yOff = p.y * gridSize; - if (quadrant.equals(Quadrant.NORTH_EAST.name())) { - yOff = yOff - gridSize; - } else if (quadrant.equals(Quadrant.SOUTH_WEST.name())) { - xOff = xOff - gridSize; - } else if (quadrant.equals(Quadrant.NORTH_WEST.name())) { - xOff = xOff - gridSize; - yOff = yOff - gridSize; + switch (q) { + case NORTH_EAST -> { + yOff = yOff - gridSize; + } + case SOUTH_WEST -> { + xOff = xOff - gridSize; + } + case NORTH_WEST -> { + xOff = xOff - gridSize; + yOff = yOff - gridSize; + } + case SOUTH_EAST -> { + // Nothing to do. + } } int rx = getVertex().x + getXMult(q) * xOff + ((getXMult(q) - 1) / 2) * gridSize; @@ -473,11 +456,6 @@ public Area getArea() { @Override public DrawableDto toDto() { - - if (getQuadrant() == null) { - calcPath(); // force calculation of the quadrent - } - var dto = LineCellTemplateDto.newBuilder(); dto.setId(getId().toString()) .setLayer(getLayer().name()) @@ -485,11 +463,8 @@ public DrawableDto toDto() { .setRadius(getRadius()) .setVertex(getVertex().toDto()); - if (getQuadrant() != null) { - dto.setQuadrant(getQuadrant().name()); - } - if (getPathVertex() != null) { - dto.setPathVertex(getPathVertex().toDto()); + if (pathVertex != null) { + dto.setPathVertex(pathVertex.toDto()); } if (getName() != null) { diff --git a/src/main/proto/drawing_dto.proto b/src/main/proto/drawing_dto.proto index b0bf6997bf..a654e44b91 100644 --- a/src/main/proto/drawing_dto.proto +++ b/src/main/proto/drawing_dto.proto @@ -126,8 +126,7 @@ message LineCellTemplateDto { string zoneId = 4; IntPointDto vertex = 5; int32 radius = 6; - string quadrant = 7; - IntPointDto path_vertex = 8; + IntPointDto path_vertex = 7; } message RadiusCellTemplateDto {