/** Constructor for case (2). * Generate an endpoint, given a single cutoff plane plus upper and lower edge points. *@param point is the center point. *@param cutoffPlane is the plane from the adjoining path segment marking the boundary between this endpoint and that segment. */ public SegmentEndpoint(final GeoPoint point, final SidedPlane cutoffPlane) { this.point = point; this.cutoffPlanes = new Membership[]{new SidedPlane(cutoffPlane)}; this.notablePoints = new GeoPoint[]{point}; }
/** Constructor for case (3). * Generate an endpoint, given two cutoff planes. *@param point is the center. *@param cutoffPlane1 is one adjoining path segment cutoff plane. *@param cutoffPlane2 is another adjoining path segment cutoff plane. */ public SegmentEndpoint(final GeoPoint point, final SidedPlane cutoffPlane1, final SidedPlane cutoffPlane2) { this.point = point; this.cutoffPlanes = new Membership[]{new SidedPlane(cutoffPlane1), new SidedPlane(cutoffPlane2)}; this.notablePoints = new GeoPoint[]{point}; }
public CircleSlice(SidedPlane circlePlane, GeoPoint endPoint1, GeoPoint endPoint2, GeoPoint center, GeoPoint check) { this.circlePlane = circlePlane; this.plane1 = new SidedPlane(check, endPoint1, center); this.plane2 = new SidedPlane(check, endPoint2, center); this.notableEdgePoints = new GeoPoint[] {endPoint1, endPoint2}; }
/** Construct a path segment. *@param planetModel is the planet model. *@param start is the starting point. *@param end is the ending point. *@param normalizedConnectingPlane is the connecting plane. */ public PathSegment(final PlanetModel planetModel, final GeoPoint start, final GeoPoint end, final Plane normalizedConnectingPlane) { this.start = start; this.end = end; this.normalizedConnectingPlane = normalizedConnectingPlane; // Cutoff planes use opposite endpoints as correct side examples startCutoffPlane = new SidedPlane(end, normalizedConnectingPlane, start); endCutoffPlane = new SidedPlane(start, normalizedConnectingPlane, end); connectingPlanePoints = new GeoPoint[]{start, end}; }
/** * It builds from 4 points given in CCW. It must be convex or logic will fail. * *@param planetModel is the planet model. *@param point1 the first point. *@param point2 the second point. *@param point3 the third point. *@param point4 the four point. */ public GeoS2Shape(final PlanetModel planetModel, GeoPoint point1, GeoPoint point2, GeoPoint point3, GeoPoint point4) { super(planetModel); this.point1 = point1; this.point2 = point2; this.point3 = point3; this.point4 = point4; // Now build the four planes this.plane1 = new SidedPlane(point4, point1, point2); this.plane2 = new SidedPlane(point1, point2, point3); this.plane3 = new SidedPlane(point2, point3, point4); this.plane4 = new SidedPlane(point3, point4, point1); //collect the notable points for the planes this.plane1Points = new GeoPoint[]{point1, point2}; this.plane2Points = new GeoPoint[]{point2, point3}; this.plane3Points = new GeoPoint[]{point3, point4}; this.plane4Points = new GeoPoint[]{point4, point1}; this.edgePoints = new GeoPoint[]{point1}; }
/** Constructor for case (2.5). * Generate an endpoint, given two cutoff planes plus upper and lower edge points. *@param point is the center. *@param cutoffPlane1 is one adjoining path segment cutoff plane. *@param cutoffPlane2 is another adjoining path segment cutoff plane. *@param topEdgePoint is a point on the cutoffPlane that should be also on the circle plane. *@param bottomEdgePoint is another point on the cutoffPlane that should be also on the circle plane. */ public SegmentEndpoint(final GeoPoint point, final SidedPlane cutoffPlane1, final SidedPlane cutoffPlane2, final GeoPoint topEdgePoint, final GeoPoint bottomEdgePoint) { this.point = point; this.cutoffPlanes = new Membership[]{new SidedPlane(cutoffPlane1), new SidedPlane(cutoffPlane2)}; this.notablePoints = new GeoPoint[]{topEdgePoint, bottomEdgePoint}; // To construct the plane, we now just need D, which is simply the negative of the evaluation of the circle normal vector at one of the points. this.circlePlane = SidedPlane.constructNormalizedPerpendicularSidedPlane(point, cutoffPlane1, topEdgePoint, bottomEdgePoint); }
/** Constructor for case (2). * Generate an endpoint, given a single cutoff plane plus upper and lower edge points. *@param point is the center point. *@param cutoffPlane is the plane from the adjoining path segment marking the boundary between this endpoint and that segment. *@param topEdgePoint is a point on the cutoffPlane that should be also on the circle plane. *@param bottomEdgePoint is another point on the cutoffPlane that should be also on the circle plane. */ public SegmentEndpoint(final GeoPoint point, final SidedPlane cutoffPlane, final GeoPoint topEdgePoint, final GeoPoint bottomEdgePoint) { this.point = point; this.cutoffPlanes = new Membership[]{new SidedPlane(cutoffPlane)}; this.notablePoints = new GeoPoint[]{topEdgePoint, bottomEdgePoint}; // To construct the plane, we now just need D, which is simply the negative of the evaluation of the circle normal vector at one of the points. this.circlePlane = SidedPlane.constructNormalizedPerpendicularSidedPlane(point, cutoffPlane, topEdgePoint, bottomEdgePoint); }
this.leftPlane = new SidedPlane(centerPoint, cosLeftLon, sinLeftLon); this.rightPlane = new SidedPlane(centerPoint, cosRightLon, sinRightLon); this.backingPlane = new SidedPlane(this.centerPoint, cosMiddleLon, sinMiddleLon, 0.0, 0.0);
/** Constructor. *@param planetModel is the planet model. *@param topLat is the top latitude of the zone. */ public GeoSouthLatitudeZone(final PlanetModel planetModel, final double topLat) { super(planetModel); this.topLat = topLat; final double sinTopLat = Math.sin(topLat); this.cosTopLat = Math.cos(topLat); // Compute an interior point. Pick one whose lat is between top and bottom. final double middleLat = (topLat - Math.PI * 0.5) * 0.5; final double sinMiddleLat = Math.sin(middleLat); this.interiorPoint = new GeoPoint(planetModel, sinMiddleLat, 0.0, Math.sqrt(1.0 - sinMiddleLat * sinMiddleLat), 1.0); this.topBoundaryPoint = new GeoPoint(planetModel, sinTopLat, 0.0, Math.sqrt(1.0 - sinTopLat * sinTopLat), 1.0); this.topPlane = new SidedPlane(interiorPoint, planetModel, sinTopLat); this.edgePoints = new GeoPoint[]{topBoundaryPoint}; }
/** Constructor. *@param planetModel is the planet model to use. *@param topLat is the top latitude. *@param bottomLat is the bottom latitude. */ public GeoLatitudeZone(final PlanetModel planetModel, final double topLat, final double bottomLat) { super(planetModel); this.topLat = topLat; this.bottomLat = bottomLat; final double sinTopLat = Math.sin(topLat); final double sinBottomLat = Math.sin(bottomLat); this.cosTopLat = Math.cos(topLat); this.cosBottomLat = Math.cos(bottomLat); // Compute an interior point. Pick one whose lat is between top and bottom. final double middleLat = (topLat + bottomLat) * 0.5; final double sinMiddleLat = Math.sin(middleLat); this.interiorPoint = new GeoPoint(planetModel, sinMiddleLat, 0.0, Math.sqrt(1.0 - sinMiddleLat * sinMiddleLat), 1.0); this.topBoundaryPoint = new GeoPoint(planetModel, sinTopLat, 0.0, Math.sqrt(1.0 - sinTopLat * sinTopLat), 1.0); this.bottomBoundaryPoint = new GeoPoint(planetModel, sinBottomLat, 0.0, Math.sqrt(1.0 - sinBottomLat * sinBottomLat), 1.0); this.topPlane = new SidedPlane(interiorPoint, planetModel, sinTopLat); this.bottomPlane = new SidedPlane(interiorPoint, planetModel, sinBottomLat); this.edgePoints = new GeoPoint[]{topBoundaryPoint, bottomBoundaryPoint}; }
/** Constructor. *@param planetModel is the planet model. *@param bottomLat is the bottom latitude. */ public GeoNorthLatitudeZone(final PlanetModel planetModel, final double bottomLat) { super(planetModel); this.bottomLat = bottomLat; final double sinBottomLat = Math.sin(bottomLat); this.cosBottomLat = Math.cos(bottomLat); // Compute an interior point. Pick one whose lat is between top and bottom. final double middleLat = (Math.PI * 0.5 + bottomLat) * 0.5; final double sinMiddleLat = Math.sin(middleLat); this.interiorPoint = new GeoPoint(planetModel, sinMiddleLat, 0.0, Math.sqrt(1.0 - sinMiddleLat * sinMiddleLat), 1.0); this.bottomBoundaryPoint = new GeoPoint(planetModel, sinBottomLat, 0.0, Math.sqrt(1.0 - sinBottomLat * sinBottomLat), 1.0); this.bottomPlane = new SidedPlane(interiorPoint, planetModel, sinBottomLat); this.edgePoints = new GeoPoint[]{bottomBoundaryPoint}; }
/** * Accepts only values in the following ranges: lon: {@code -PI -> PI} */ public GeoDegenerateLongitudeSlice(final PlanetModel planetModel, final double longitude) { super(planetModel); // Argument checking if (longitude < -Math.PI || longitude > Math.PI) throw new IllegalArgumentException("Longitude out of range"); this.longitude = longitude; final double sinLongitude = Math.sin(longitude); final double cosLongitude = Math.cos(longitude); this.plane = new Plane(cosLongitude, sinLongitude); // We need a bounding plane too, which is perpendicular to the longitude plane and sided so that the point (0.0, longitude) is inside. this.interiorPoint = new GeoPoint(planetModel, 0.0, sinLongitude, 1.0, cosLongitude); this.boundingPlane = new SidedPlane(interiorPoint, -sinLongitude, cosLongitude); this.edgePoints = new GeoPoint[]{interiorPoint}; this.planePoints = new GeoPoint[]{planetModel.NORTH_POLE, planetModel.SOUTH_POLE}; }
public Edge(final PlanetModel pm, final GeoPoint startPoint, final GeoPoint endPoint) { this.startPoint = startPoint; this.endPoint = endPoint; this.notablePoints = new GeoPoint[]{startPoint, endPoint}; this.plane = new Plane(startPoint, endPoint); this.startPlane = new SidedPlane(endPoint, plane, startPoint); this.endPlane = new SidedPlane(startPoint, plane, endPoint); final GeoPoint interpolationPoint = plane.interpolate(pm, startPoint, endPoint, halfProportions)[0]; this.backingPlane = new SidedPlane(interpolationPoint, interpolationPoint, 0.0); this.planeBounds = new XYZBounds(); this.planeBounds.addPoint(startPoint); this.planeBounds.addPoint(endPoint); this.planeBounds.addPlane(pm, this.plane, this.startPlane, this.endPlane, this.backingPlane); //System.out.println("Recording edge ["+startPoint+" --> "+endPoint+"]; bounds = "+planeBounds); }
public SectorLinearCrossingEdgeIterator(final GeoPoint testPoint, final Plane plane, final Plane abovePlane, final Plane belowPlane, final double thePointX, final double thePointY, final double thePointZ) { assert plane.evaluateIsZero(thePointX, thePointY, thePointZ) : "Check point is not on travel plane"; assert plane.evaluateIsZero(testPoint) : "Test point is not on travel plane"; this.testPoint = testPoint; this.plane = plane; this.abovePlane = abovePlane; this.belowPlane = belowPlane; // We have to be sure we don't accidently create two bounds that would exclude all points. // Not sure this can happen but... final SidedPlane bound1Plane = new SidedPlane(thePointX, thePointY, thePointZ, plane, testPoint); final SidedPlane bound2Plane = new SidedPlane(testPoint, plane, thePointX, thePointY, thePointZ); if (bound1Plane.isNumericallyIdentical(bound2Plane)) { throw new IllegalArgumentException("Sector iterator unreliable when bounds planes are numerically identical"); } this.bound1 = bound1Plane; this.bound2 = bound2Plane; this.thePointX = thePointX; this.thePointY = thePointY; this.thePointZ = thePointZ; //System.out.println(" Constructing sector linear crossing edge iterator"); //debugIntersectAllEdges(plane, bound1, bound2); }
/** * Sole constructor * *@param planetModel is the planet model. *@param minX is the minimum X value. *@param maxX is the maximum X value. *@param Y is the Y value. *@param Z is the Z value. */ public XdYdZSolid(final PlanetModel planetModel, final double minX, final double maxX, final double Y, final double Z) { super(planetModel); // Argument checking if (maxX - minX < Vector.MINIMUM_RESOLUTION) throw new IllegalArgumentException("X values in wrong order or identical"); this.minX = minX; this.maxX = maxX; this.Y = Y; this.Z = Z; // Build the planes and intersect them. final Plane yPlane = new Plane(yUnitVector,-Y); final Plane zPlane = new Plane(zUnitVector,-Z); final SidedPlane minXPlane = new SidedPlane(maxX,0.0,0.0,xUnitVector,-minX); final SidedPlane maxXPlane = new SidedPlane(minX,0.0,0.0,xUnitVector,-maxX); surfacePoints = yPlane.findIntersections(planetModel,zPlane,minXPlane,maxXPlane); }
/** * Sole constructor * *@param planetModel is the planet model. *@param X is the X value. *@param minY is the minimum Y value. *@param maxY is the maximum Y value. *@param Z is the Z value. */ public dXYdZSolid(final PlanetModel planetModel, final double X, final double minY, final double maxY, final double Z) { super(planetModel); // Argument checking if (maxY - minY < Vector.MINIMUM_RESOLUTION) throw new IllegalArgumentException("Y values in wrong order or identical"); this.X = X; this.minY = minY; this.maxY = maxY; this.Z = Z; // Build the planes and intersect them. final Plane xPlane = new Plane(xUnitVector,-X); final Plane zPlane = new Plane(zUnitVector,-Z); final SidedPlane minYPlane = new SidedPlane(0.0,maxY,0.0,yUnitVector,-minY); final SidedPlane maxYPlane = new SidedPlane(0.0,minY,0.0,yUnitVector,-maxY); surfacePoints = xPlane.findIntersections(planetModel,zPlane,minYPlane,maxYPlane); }
/** * Sole constructor * *@param planetModel is the planet model. *@param X is the X value. *@param Y is the Y value. *@param minZ is the minimum Z value. *@param maxZ is the maximum Z value. */ public dXdYZSolid(final PlanetModel planetModel, final double X, final double Y, final double minZ, final double maxZ) { super(planetModel); // Argument checking if (maxZ - minZ < Vector.MINIMUM_RESOLUTION) throw new IllegalArgumentException("Z values in wrong order or identical"); this.X = X; this.Y = Y; this.minZ = minZ; this.maxZ = maxZ; // Build the planes and intersect them. final Plane xPlane = new Plane(xUnitVector,-X); final Plane yPlane = new Plane(yUnitVector,-Y); final SidedPlane minZPlane = new SidedPlane(0.0,0.0,maxZ,zUnitVector,-minZ); final SidedPlane maxZPlane = new SidedPlane(0.0,0.0,minZ,zUnitVector,-maxZ); surfacePoints = xPlane.findIntersections(planetModel,yPlane,minZPlane,maxZPlane); }
/** Construct a sided plane from two points and a third normal vector. */ public static SidedPlane constructNormalizedPerpendicularSidedPlane(final Vector insidePoint, final Vector normalVector, final Vector point1, final Vector point2) { final Vector pointsVector = new Vector(point1.x - point2.x, point1.y - point2.y, point1.z - point2.z); final Vector newNormalVector = new Vector(normalVector, pointsVector); try { // To construct the plane, we now just need D, which is simply the negative of the evaluation of the circle normal vector at one of the points. return new SidedPlane(insidePoint, newNormalVector, -newNormalVector.dotProduct(point1)); } catch (IllegalArgumentException e) { return null; } }
public FullLinearCrossingEdgeIterator(final GeoPoint testPoint, final Plane plane, final Plane abovePlane, final Plane belowPlane, final double thePointX, final double thePointY, final double thePointZ) { assert plane.evaluateIsZero(thePointX, thePointY, thePointZ) : "Check point is not on travel plane"; assert plane.evaluateIsZero(testPoint) : "Test point is not on travel plane"; this.testPoint = testPoint; this.plane = plane; this.abovePlane = abovePlane; this.belowPlane = belowPlane; if (plane.isNumericallyIdentical(testPoint)) { throw new IllegalArgumentException("Plane vector identical to testpoint vector"); } // It doesn't matter which 1/2 of the world we choose, but we must choose only one. this.bound = new SidedPlane(plane, testPoint); this.thePointX = thePointX; this.thePointY = thePointY; this.thePointZ = thePointZ; //System.out.println(" Constructing full linear crossing edge iterator"); //debugIntersectAllEdges(plane, bound); }
point1.x - point2.x, point1.y - point2.y, point1.z - point2.z, point2.x - point3.x, point2.y - point3.y, point2.z - point3.z); rval = new SidedPlane(insidePoint, planeNormal, -planeNormal.dotProduct(point2)); } catch (IllegalArgumentException e) { point1.x - point3.x, point1.y - point3.y, point1.z - point3.z, point3.x - point2.x, point3.y - point2.y, point3.z - point2.z); rval = new SidedPlane(insidePoint, planeNormal, -planeNormal.dotProduct(point3)); } catch (IllegalArgumentException e) { point3.x - point1.x, point3.y - point1.y, point3.z - point1.z, point1.x - point2.x, point1.y - point2.y, point1.z - point2.z); rval = new SidedPlane(insidePoint, planeNormal, -planeNormal.dotProduct(point1)); } catch (IllegalArgumentException e) {