Skip to content
80 changes: 62 additions & 18 deletions common/src/main/java/net/rptools/lib/GeometryUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,17 @@

import java.awt.Shape;
import java.awt.geom.Area;
import java.awt.geom.Line2D;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.locationtech.jts.algorithm.InteriorPointArea;
import org.locationtech.jts.algorithm.Orientation;
import org.locationtech.jts.algorithm.PointLocation;
import org.locationtech.jts.awt.ShapeReader;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.CoordinateArrays;
import org.locationtech.jts.geom.Envelope;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.LinearRing;
import org.locationtech.jts.geom.Location;
import org.locationtech.jts.geom.MultiPolygon;
import org.locationtech.jts.geom.Polygon;
import org.locationtech.jts.geom.PrecisionModel;
import org.locationtech.jts.geom.*;
import org.locationtech.jts.geom.util.GeometryFixer;
import org.locationtech.jts.operation.valid.IsValidOp;
import org.locationtech.jts.precision.GeometryPrecisionReducer;
Expand Down Expand Up @@ -91,8 +79,8 @@ public static Area union(Collection<Area> areas) {
}

/**
* Like {@link #union(java.util.Collection)}, but will modify the areas and collection for
* performance gains.
* Like {@link #union(Collection)}, but will modify the areas and collection for performance
* gains.
*
* @param areas The areas to union.
* @return The union of {@code areas}
Expand Down Expand Up @@ -137,6 +125,62 @@ public static MultiPolygon toJts(Shape shape) {
return geometry;
}

/**
* Use for a simple shape that is a closed polygon without holes.
*
* @param shape a closed polygon
* @return LinearRing geometry
*/
public static LinearRing shapeToLinearRing(Shape shape) {
List<Coordinate> coordinates = new ArrayList<>();
final PathIterator iterator = shape.getPathIterator(null);
final double[] pathCoordinate = new double[2];
iterator.currentSegment(pathCoordinate);
coordinates.add(new CoordinateXY(pathCoordinate[0], pathCoordinate[1]));
iterator.next();
while (!iterator.isDone()) {
iterator.currentSegment(pathCoordinate);
coordinates.add(new CoordinateXY(pathCoordinate[0], pathCoordinate[1]));
iterator.next();
}
coordinates.add(coordinates.getFirst()); // close the polygon
return getGeometryFactory().createLinearRing(coordinates.toArray(Coordinate[]::new));
}

/**
* Converts a line2D to the jts geometry LinearString
*
* @param line2D line to convert
* @return LinearString geometry
*/
public static LineString line2DToLinearString(final Line2D line2D) {
return getGeometryFactory()
.createLineString(
new Coordinate[] {
GeometryUtil.point2DToCoordinate(line2D.getP1()),
GeometryUtil.point2DToCoordinate(line2D.getP2())
});
}

/**
* Find the points of intersection between a line and a shape
*
* @param line the intersecting line
* @param shape the shape to intersect
* @return Array of intersecting points
*/
public static Point2D[] lineSegmentShapeIntersection(final Line2D line, final Shape shape) {
LineString lineString = line2DToLinearString(line);
LinearRing linearRing = shapeToLinearRing(shape);
Geometry intersection = lineString.intersection(linearRing);
if (intersection.getNumPoints() > 0) {
return Arrays.stream(intersection.getCoordinates())
.map(GeometryUtil::coordinateToPoint2D)
.toArray(Point2D[]::new);
}
return new Point2D.Double[] {};
}

public static Collection<Polygon> toJtsPolygons(Shape shape) {
if (shape instanceof Area area && area.isEmpty()) {
return Collections.emptyList();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1831,7 +1831,7 @@ private void doDragTo(ZonePoint newAnchorPoint) {
}

// Don't bother if there isn't any movement
if (!renderer.hasMoveSelectionSetMoved(tokenBeingDragged.getId(), newAnchorPoint)) {
if (renderer.isMoveSelectionSetUnchanged(tokenBeingDragged.getId(), newAnchorPoint)) {
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1206,7 +1206,7 @@ public void moveByKey(int dx, int dy, boolean micro) {

private void doDragTo(ZonePoint newAnchorPoint) {
// Don't bother if there isn't any movement
if (!renderer.hasMoveSelectionSetMoved(tokenBeingDragged.getId(), newAnchorPoint)) {
if (renderer.isMoveSelectionSetUnchanged(tokenBeingDragged.getId(), newAnchorPoint)) {
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
*/
package net.rptools.maptool.client.ui.token;

import java.awt.AlphaComposite;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import net.rptools.maptool.model.Token;
Expand Down Expand Up @@ -52,11 +51,6 @@ protected BooleanTokenOverlay(String aName) {
@Override
public void paintOverlay(Graphics2D g, Token token, Rectangle bounds, Object value) {
if (FunctionUtil.getBooleanValue(value)) {
// Apply Alpha Transparency
float opacity = token.getTokenOpacity();
if (opacity < 1.0f)
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, opacity));

paintOverlay(g, token, bounds);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@
*/
package net.rptools.maptool.client.ui.token;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;
Expand Down Expand Up @@ -78,7 +76,6 @@ public Object clone() {
public void paintOverlay(Graphics2D g, Token aToken, Rectangle bounds) {
Color tempColor = g.getColor();
Stroke tempStroke = g.getStroke();
Composite tempComposite = g.getComposite();
try {
g.setColor(getColor());
g.setStroke(getStroke());
Expand All @@ -101,14 +98,10 @@ public void paintOverlay(Graphics2D g, Token aToken, Rectangle bounds) {
break;
} // endswitch
Shape s = new Ellipse2D.Double(x, y, size, size);
if (getOpacity() != 100)
g.setComposite(
AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float) getOpacity() / 100));
g.fill(s);
} finally {
g.setColor(tempColor);
g.setStroke(tempStroke);
g.setComposite(tempComposite);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@
*/
package net.rptools.maptool.client.ui.token;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Stroke;
Expand Down Expand Up @@ -74,17 +72,12 @@ public void paintOverlay(Graphics2D g, Token aToken, Rectangle bounds) {
g.setColor(getColor());
Stroke tempStroke = g.getStroke();
g.setStroke(getStroke());
Composite tempComposite = g.getComposite();
if (getOpacity() != 100)
g.setComposite(
AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float) getOpacity() / 100));
g.draw(
new Line2D.Double(0, (double) bounds.height / 2, bounds.width, (double) bounds.height / 2));
g.draw(
new Line2D.Double((double) bounds.width / 2, 0, (double) bounds.width / 2, bounds.height));
g.setColor(tempColor);
g.setStroke(tempStroke);
g.setComposite(tempComposite);
}

public static CrossTokenOverlay fromDto(BooleanTokenOverlayDto dto) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@
*/
package net.rptools.maptool.client.ui.token;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Stroke;
Expand Down Expand Up @@ -76,17 +74,13 @@ public void paintOverlay(Graphics2D g, Token aToken, Rectangle bounds) {
g.setColor(getColor());
Stroke tempStroke = g.getStroke();
g.setStroke(getStroke());
Composite tempComposite = g.getComposite();
if (getOpacity() != 100)
g.setComposite(
AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float) getOpacity() / 100));

g.draw(new Line2D.Double(0, vc, hc, 0));
g.draw(new Line2D.Double(hc, 0, bounds.width, vc));
g.draw(new Line2D.Double(bounds.width, vc, hc, bounds.height));
g.draw(new Line2D.Double(hc, bounds.height, 0, vc));
g.setColor(tempColor);
g.setStroke(tempStroke);
g.setComposite(tempComposite);
}

public static DiamondTokenOverlay fromDto(BooleanTokenOverlayDto dto) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@
*/
package net.rptools.maptool.client.ui.token;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;
Expand Down Expand Up @@ -91,19 +89,14 @@ protected TokenOverlayFlow getFlow() {
public void paintOverlay(Graphics2D g, Token aToken, Rectangle bounds) {
Color tempColor = g.getColor();
Stroke tempStroke = g.getStroke();
Composite tempComposite = g.getComposite();
try {
g.setColor(getColor());
g.setStroke(getStroke());
if (getOpacity() != 100)
g.setComposite(
AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float) getOpacity() / 100));
Shape s = getShape(bounds, aToken);
g.fill(s);
} finally {
g.setColor(tempColor);
g.setStroke(tempStroke);
g.setComposite(tempComposite);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,7 @@ public void paintOverlay(Graphics2D g, Token token, Rectangle bounds) {
int height = size.height;
int x = iBounds.x + (d.width - width) / 2;
int y = iBounds.y + (d.height - height) / 2;
Composite tempComposite = g.getComposite();
if (getOpacity() != 100)
g.setComposite(
AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float) getOpacity() / 100));
g.drawImage(image, x, y, size.width, size.height, null);
g.setComposite(tempComposite);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
*/
package net.rptools.maptool.client.ui.token;

import java.awt.AlphaComposite;
import java.awt.Composite;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Rectangle;
Expand Down Expand Up @@ -98,13 +96,7 @@ public void paintOverlay(Graphics2D g, Token token, Rectangle bounds, double val
y = d.height - size.height;
}

Composite tempComposite = g.getComposite();
if (getOpacity() != 100) {
g.setComposite(
AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float) getOpacity() / 100));
}
g.drawImage(image, x, y, size.width, size.height, null);
g.setComposite(tempComposite);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@
*/
package net.rptools.maptool.client.ui.token;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Stroke;
Expand Down Expand Up @@ -73,17 +71,12 @@ public void paintOverlay(Graphics2D g, Token aToken, Rectangle bounds) {
g.setColor(getColor());
Stroke tempStroke = g.getStroke();
g.setStroke(getStroke());
Composite tempComposite = g.getComposite();
if (getOpacity() != 100)
g.setComposite(
AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float) getOpacity() / 100));
double offset = getStroke().getLineWidth() / 2.0;
g.draw(
new Ellipse2D.Double(
0 + offset, 0 + offset, bounds.width - offset * 2, bounds.height - offset * 2));
g.setColor(tempColor);
g.setStroke(tempStroke);
g.setComposite(tempComposite);
}

public static OTokenOverlay fromDto(BooleanTokenOverlayDto dto) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@
*/
package net.rptools.maptool.client.ui.token;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import net.rptools.maptool.model.Token;
Expand Down Expand Up @@ -71,13 +69,8 @@ public ShadedTokenOverlay(String aName, Color aColor) {
public void paintOverlay(Graphics2D g, Token aToken, Rectangle bounds) {
Color temp = g.getColor();
g.setColor(color);
Composite tempComposite = g.getComposite();
if (getOpacity() != 100)
g.setComposite(
AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float) getOpacity() / 100));
g.fill(bounds);
g.setColor(temp);
g.setComposite(tempComposite);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
*/
package net.rptools.maptool.client.ui.token;

import java.awt.AlphaComposite;
import java.awt.Composite;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Rectangle;
Expand Down Expand Up @@ -95,11 +93,6 @@ public void paintOverlay(Graphics2D g, Token token, Rectangle bounds, double val
y = d.height - size.height;
}

Composite tempComposite = g.getComposite();
if (getOpacity() != 100) {
g.setComposite(
AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float) getOpacity() / 100));
}
int width =
(getSide() == Side.TOP || getSide() == Side.BOTTOM)
? calcBarSize(image.getWidth(), value)
Expand Down Expand Up @@ -129,7 +122,6 @@ public void paintOverlay(Graphics2D g, Token token, Rectangle bounds, double val
image.getWidth(),
image.getHeight(),
null);
g.setComposite(tempComposite);
}

/**
Expand Down
Loading
Loading