/** * Calculate the number of times to split the edges of the shape for geometry assembly. * * @param rc current RenderContext * * @return an even number of intervals */ protected int computeIntervals(RenderContext rc) { int intervals = MIN_INTERVALS; if (intervals >= this.maximumIntervals) { return intervals; // use at least the minimum number of intervals } Vec3 centerPoint = rc.geographicToCartesian(this.center.latitude, this.center.longitude, this.center.altitude, this.altitudeMode, scratchPoint); double maxRadius = Math.max(this.majorRadius, this.minorRadius); double cameraDistance = centerPoint.distanceTo(rc.cameraPoint) - maxRadius; if (cameraDistance <= 0) { return this.maximumIntervals; // use the maximum number of intervals when the camera is very close } double metersPerPixel = rc.pixelSizeAtDistance(cameraDistance); double circumferencePixels = this.computeCircumference() / metersPerPixel; double circumferenceIntervals = circumferencePixels / this.maximumPixelsPerInterval; double subdivisions = Math.log(circumferenceIntervals / intervals) / Math.log(2); int subdivisionCount = Math.max(0, (int) Math.ceil(subdivisions)); intervals <<= subdivisionCount; // subdivide the base intervals to achieve the desired number of intervals return Math.min(intervals, this.maximumIntervals); // don't exceed the maximum number of intervals }
@Test public void testCircumference_Circle() { Ellipse ellipse = new Ellipse(); double major = 50; double minor = 50; ellipse.setMajorRadius(major); ellipse.setMinorRadius(minor); double expectedCircumference = 2 * Math.PI * major; double actualCircumference = ellipse.computeCircumference(); assertEquals("circle circumference", expectedCircumference, actualCircumference, 1e-9); } }