@Override public Geom buffer(double amt, Linearizer linearizer, Tolerance tolerance) throws IllegalArgumentException, NullPointerException { if (amt == 0) { return this; } else if (amt < 0) { return null; } VectList result = new VectList(); VectBuilder vect = new VectBuilder(); projectOutward(0, -amt, tolerance, vect); double ix = vect.getX(); double iy = vect.getY(); result.add(ix, iy); projectOutward(0, amt, tolerance, vect); linearizer.linearizeSegment(ax, ay, ix, iy, vect.getX(), vect.getY(), result); projectOutward(1, amt, tolerance, vect); double jx = vect.getX(); double jy = vect.getY(); result.add(jx, jy); projectOutward(1, -amt, tolerance, vect); linearizer.linearizeSegment(bx, by, jx, jy, vect.getX(), vect.getY(), result); result.add(ix, iy); return new Area(new Ring(result, null)); }
static void intersectionLineCircleInternal( double ax, double ay, double bx, double by, double cx, double cy, double radius, Tolerance tolerance, VectBuilder working, VectList intersections) { projectOnToLineInternal( ax, ay, bx, by, cx, cy, tolerance, working); // get the closest point on the line to the circle center double dx = working.getX(); double dy = working.getY(); double distToLineSq = Vect.distSq(cx, cy, dx, dy); double radiusSq = radius * radius; switch (tolerance.check(distToLineSq - radiusSq)) { case 1: // dist to line is greater than radius - line does not intersect circle return; case 0: // dist to line matches radius - line touches circle intersections.add(dx, dy); return; default: // dist to line is less than radius - line crosses circle double mx = bx - ax; double my = by - ay; double segmentLen = Math.sqrt(mx * mx + my * my); double projectDist; if (tolerance.check(distToLineSq) == 0) { // line crosses circle center projectDist = radius; dx = cx; dy = cy; } else { projectDist = Math.sqrt(radiusSq - distToLineSq); } double mul = projectDist / segmentLen; mx *= mul; my *= mul; intersections.add(dx - mx, dy - my); intersections.add(dx + mx, dy + my); } }