@Test public void testCollinear() { CircularArc arc = new CircularArc(0, 0, 0, 10, 0, 20); assertEquals(CircularArc.COLLINEARS, arc.getRadius(), 0d); assertCoordinateEquals(null, arc.getCenter()); double[] linearized = arc.linearize(0); assertArrayEquals(new double[] {0, 0, 0, 10, 0, 20}, linearized, 0d); assertEquals(envelopeFrom(arc), arc.getEnvelope()); }
Coordinate center = arc.getCenter(); double radius = arc.getRadius(); double[] cp = arc.getControlPoints(); double angle1 = Math.atan2(cp[1] - center.y, cp[0] - center.x); double angle2 = Math.atan2(cp[3] - center.y, cp[2] - center.x);
GrowableOrdinateArray linearize(double tolerance, GrowableOrdinateArray array) { initializeCenterRadius(); if (tolerance < 0) { throw new IllegalArgumentException( } else { segmentsPerQuadrant = BASE_SEGMENTS_QUADRANT; double currentTolerance = computeChordCircleDistance(segmentsPerQuadrant); if (currentTolerance < tolerance) { while (currentTolerance < tolerance && segmentsPerQuadrant > 1) { currentTolerance = computeChordCircleDistance(segmentsPerQuadrant); currentTolerance = computeChordCircleDistance(segmentsPerQuadrant); if (!isWhole((ma - angle) / step)) { points++; if (equals(angle, ma)) { angle += step; array.add(x, y); double next = angle + step; if (angle < ma && next > ma && !equals(angle, ma) && !equals(next, ma)) { array.add(mx, my);
/** * Returns the circle containing this arc * * @return */ public static CircularRing toCircle( CircularArc arc, GeometryFactory geometryFactory, double tolerance) { double radius = arc.getRadius(); Coordinate center = arc.getCenter(); double[] rcp = new double[10]; rcp[0] = center.x + radius; rcp[1] = center.y; rcp[2] = center.x; rcp[3] = center.y + radius; rcp[4] = center.x - radius; rcp[5] = center.y; rcp[6] = center.x; rcp[7] = center.y - radius; rcp[8] = center.x + radius; rcp[9] = center.y; return new CircularRing(rcp, geometryFactory, tolerance); }
public double[] linearize(double tolerance) { initializeCenterRadius(); // the collinear case is simple, we just return the control points (and do the same for same // points case) if (radius == COLLINEARS || radius == 0) { return controlPoints; } return linearize(tolerance, new GrowableOrdinateArray()).getData(); }
public ArcScan() { if (controlPoints.length == 3) { // single arc case CircularArc arc = new CircularArc(controlPoints); visitArc(arc); } else { // go over each 3-points set and linearize it double[] arcControlPoints = new double[6]; CircularArc arc = new CircularArc(arcControlPoints); for (int i = 0; i <= controlPoints.length - 6; i += 4) { // have the arc work off the new control points System.arraycopy(controlPoints, i, arcControlPoints, 0, 6); arc.reset(); visitArc(arc); } } }
@Test public void testMidMatchSequence() { Circle circle = new Circle(100); // create control points that will match exactly the points the algo should generate double halfStep = CircularArc.HALF_PI / 64; CircularArc arc = circle.getCircularArc(halfStep, halfStep * 2, halfStep * 5); assertEquals(100, arc.getRadius(), 1e-9); assertCoordinateEquals(ORIGIN, arc.getCenter()); // linearize, we should get back the control points, plus the regular points in the middle double[] expected = circle.samplePoints(halfStep, halfStep * 2, halfStep * 4, halfStep * 5); assertArrayEquals(expected, arc.linearize(0.2), Circle.EPS); }
double radius = first.getRadius(); if (radius == Double.POSITIVE_INFINITY) { return false; Coordinate center = first.getCenter(); final int numArcs = curved.getNumArcs(); for (int i = 1; i < numArcs; i++) { CircularArc curr = curved.getArcN(i); if (!CircularArc.equals(curr.getRadius(), radius)) { return false; Coordinate cc = curr.getCenter(); if (!CircularArc.equals(cc.x, center.x) || !CircularArc.equals(cc.y, center.y)) { return false; CircularArc curr = curvedComponent.getArcN(i); if (center == null) { radius = curr.getRadius(); if (radius == Double.POSITIVE_INFINITY) { return false; center = curr.getCenter(); } else { if (!CircularArc.equals(curr.getRadius(), radius)) { return false; Coordinate cc = curr.getCenter(); if (!CircularArc.equals(cc.x, center.x) || !CircularArc.equals(cc.y, center.y)) {
@Override public CircularArc getArcN(int arcIndex) { int baseIdx = arcIndex * 4; double[] arcControlPoints = new double[6]; System.arraycopy(controlPoints, baseIdx, arcControlPoints, 0, 6); CircularArc arc = new CircularArc(arcControlPoints); return arc; }
protected void visitArc(CircularArc arc) { // if it's not the first arc, we need to eliminate the last point, // as the end point of the last arc is the start point of the new one if (gar.size() > 0) { gar.setSize(gar.size() - 2); } arc.linearize(tolerance, gar); } };
@Test public void testNormalize() { double[] circleControlPoints = new double[] {0, 0, 0, 10, 0, 0}; CircularRing circle = new CircularRing(circleControlPoints, GEOMETRY_FACTORY, 1e-6); CircularRing normalized = circle.normalizeRing(); assertEquals(2, normalized.getNumArcs()); CircularArc a1 = normalized.getArcN(0); assertArrayEquals(new double[] {0, 0, 5, 5, 0, 10}, a1.getControlPoints(), 1e-6); CircularArc a2 = normalized.getArcN(1); assertArrayEquals(new double[] {0, 10, -5, 5, 0, 0}, a2.getControlPoints(), 1e-6); }
@Test public void testEndMatchSequence() { Circle circle = new Circle(100); // create control points that will match exactly the points the algo should generate double halfStep = CircularArc.HALF_PI / 64; CircularArc arc = circle.getCircularArc(halfStep, halfStep * 3, halfStep * 4); assertEquals(100, arc.getRadius(), 1e-9); assertCoordinateEquals(ORIGIN, arc.getCenter()); // linearize, we should get back only control points, plus the regular points in the middle double[] expected = circle.samplePoints(halfStep, halfStep * 3, halfStep * 4); assertArrayEquals(expected, arc.linearize(10), Circle.EPS); }
/** * Returns a curved geometry factory given the linearization constraints, the original factory, * and a coordinate sequence representing the control points of a curved geometry * * @param arcParameters * @param gFactory * @param cs * @return */ public static CurvedGeometryFactory getCurvedGeometryFactory( ArcParameters arcParameters, GeometryFactory gFactory, CoordinateSequence cs) { CurvedGeometryFactory factory; if (gFactory instanceof CurvedGeometryFactory) { factory = (CurvedGeometryFactory) gFactory; } else if (arcParameters != null && arcParameters.getLinearizationTolerance() != null) { double tolerance = Double.MAX_VALUE; if (cs != null) { CircularArc arc = CurvedGeometries.getArc(cs, 0); Circle c = new Circle(arc.getCenter(), arc.getRadius()); tolerance = arcParameters.getLinearizationTolerance().getTolerance(c); } factory = new CurvedGeometryFactory(gFactory, tolerance); } else { factory = new CurvedGeometryFactory(gFactory, Double.MAX_VALUE); } return factory; } }
public CircularArc getCircularArc(double startAngle, double midAngle, double endAngle) { double[] controlPoints = samplePoints(startAngle, midAngle, endAngle); return new CircularArc(controlPoints); }
@Test public void testMatchToleranceClockwise() { Circle circle = new Circle(100); CircularArc arc = circle.getCircularArc(Math.PI, Math.PI / 2, 0); // test with subsequently smaller tolerances, but avoid going too low or // numerical issues will byte us, this one stops roughly at 2.4e-7 double tolerance = 1; for (int i = 0; i < 12; i++) { double[] linearized = arc.linearize(tolerance); // System.out.println(tolerance + " --> " + linearized.length); assertTrue(linearized.length >= 64); circle.assertTolerance(linearized, tolerance); tolerance /= 4; } }
@Test public void testSamePoints() { CircularArc arc = new CircularArc(0, 0, 0, 0, 0, 0); assertEquals(0, arc.getRadius(), 0d); assertCoordinateEquals(ORIGIN, arc.getCenter()); double[] linearized = arc.linearize(0); assertArrayEquals(new double[] {0, 0, 0, 0, 0, 0}, linearized, 0d); assertEquals(envelopeFrom(arc), arc.getEnvelope()); assertEquals(0, arc.getEnvelope().getArea(), 0d); }
@Test public void testStartMatchSequence() { Circle circle = new Circle(100); // create control points that will match exactly the points the algo should generate double halfStep = CircularArc.HALF_PI / 64; CircularArc arc = circle.getCircularArc(0, halfStep * 3, halfStep * 5); assertEquals(100, arc.getRadius(), 1e-9); assertCoordinateEquals(ORIGIN, arc.getCenter()); // linearize, we should get back the control points, plus the regular points in the middle double[] expected = circle.samplePoints(0, halfStep * 2, halfStep * 3, halfStep * 4, halfStep * 5); assertArrayEquals(expected, arc.linearize(0.2), Circle.EPS); }
public void testCirclePolygon() throws Exception { Parser p = new Parser(gml); Object g = p.parse(GML3CurveParsingTest.class.getResourceAsStream("v3_2/circlePolygon.xml")); assertThat(g, instanceOf(CurvePolygon.class)); CurvePolygon cp = (CurvePolygon) g; assertEquals(TOLERANCE, cp.getTolerance()); assertEquals(0, cp.getNumInteriorRing()); // exterior ring checks assertTrue(cp.getExteriorRing() instanceof CircularRing); CircularRing shell = (CircularRing) cp.getExteriorRing(); assertTrue(CurvedGeometries.isCircle(shell)); CircularArc arc = shell.getArcN(0); assertEquals(5, arc.getRadius(), 0d); assertEquals(new Coordinate(15, 150), arc.getCenter()); }
/** * Builds a circular arc out of the specified coordinate sequence * * @param cs * @param startCoordinate * @return */ public static CircularArc getArc(CoordinateSequence cs, int startCoordinate) { if (cs.size() < (startCoordinate + 3)) { throw new IllegalArgumentException( "The coordinate sequence has " + cs.size() + " points, cannot extract a circular arc starting from coordinate " + startCoordinate); } else if (startCoordinate < 0) { throw new IllegalArgumentException( "Start coordinate must be 0 or positive, not: " + startCoordinate); } return new CircularArc( cs.getOrdinate(0, 0), cs.getOrdinate(0, 1), // cs.getOrdinate(1, 0), cs.getOrdinate(1, 1), // cs.getOrdinate(2, 0), cs.getOrdinate(2, 1)); }
@Test public void testMatchTolerance() { Circle circle = new Circle(100); CircularArc arc = circle.getCircularArc(0, Math.PI / 2, Math.PI); // test with subsequently smaller tolerances, but avoid going too low or // numerical issues will byte us, this one stops roughly at 2.4e-7 double tolerance = 1; for (int i = 0; i < 12; i++) { double[] linearized = arc.linearize(tolerance); // System.out.println(tolerance + " --> " + linearized.length); assertTrue(linearized.length >= 64); circle.assertTolerance(linearized, tolerance); tolerance /= 4; } }