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(); }
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 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; } }
private LineString getLinearizedArc( Circle c, double startAngle, double midAngle, double endAngle) { CircularArc arc = c.getCircularArc(startAngle, midAngle, endAngle); double[] linearized = arc.linearize(Double.MAX_VALUE); Coordinate[] coords = new Coordinate[linearized.length / 2]; for (int i = 0; i < coords.length; i++) { coords[i] = new Coordinate(linearized[i * 2], linearized[i * 2 + 1]); } CoordinateArraySequence cs = new CoordinateArraySequence(coords); return new LineString(cs, new GeometryFactory()); } }
@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; } }
@Test public void testMatchingSequence() { Circle circle = new Circle(100); // create control points that will match exactly the points the algo should generate CircularArc arc = circle.getCircularArc(0, CircularArc.HALF_PI / 32, CircularArc.HALF_PI / 16); assertEquals(100, arc.getRadius(), 1e-9); assertCoordinateEquals(ORIGIN, arc.getCenter()); // linearize with a large tolerance, we should get back just the control points assertArrayEquals(arc.getControlPoints(), arc.linearize(10), 0d); }
@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); }
@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); }
@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()); }
@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); }
@Test public void testOutsideSequence() { 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 * 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 * 3, halfStep * 4, halfStep * 5); assertArrayEquals(expected, arc.linearize(0.1), Circle.EPS); }
@Test public void testCrossPIPI() { Circle circle = new Circle(100); // create control points that will match exactly the points the algo should generate double step = CircularArc.HALF_PI / 32; CircularArc arc = circle.getCircularArc(-step * 2, step, step * 2); 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(-step * 2, -step, 0, step, step * 2); assertArrayEquals(expected, arc.linearize(0.2), Circle.EPS); assertEquals(envelopeFrom(arc, 100, 0), arc.getEnvelope()); }
@Test public void testMinuscule() { Circle circle = new Circle(100); CircularArc arc = circle.getCircularArc(0, CircularArc.HALF_PI / 128, CircularArc.HALF_PI / 64); assertEquals(100, arc.getRadius(), 1e-9); assertCoordinateEquals(ORIGIN, arc.getCenter()); // linearize with a large tolerance, we should get back just the control points assertArrayEquals(arc.getControlPoints(), arc.linearize(10), 0d); assertEquals(envelopeFrom(arc), arc.getEnvelope()); }
@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 testOutsideSequenceClockwise() { 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 * 5, halfStep * 3, halfStep); 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 * 5, halfStep * 4, halfStep * 3, halfStep * 2, halfStep); assertArrayEquals(expected, arc.linearize(0.1), Circle.EPS); assertEquals(envelopeFrom(arc), arc.getEnvelope()); }