/** * Computes the projection position of the point on the circle, by computing angle with * horizonrtal */ public double project(Point2D point) { double xp = point.x() - this.xc; double yp = point.y() - this.yc; // compute angle return Angle2D.horizontalAngle(xp, yp); }
public static ArrayList<Extrusion3D> brim(Slicer s, int count, Point2D lst) { if (count == 0) return new ArrayList<Extrusion3D>(); double z = s.layerHeight * .75; Box3D bb = s.part.boundingBox(); Surface3D plane = SimplePlane.MakePlane( bb.getMinX() - 5, bb.getMinY() - 5, bb.getMaxX() + 5, bb.getMaxY() + 5, z); LineSegment3D[] overlap = plane.overlap(s.part); ArrayList<Loop> loops = Order.ListOrder(Flatten.FlattenZ(overlap)); ArrayList<ArrayList<Extrusion2D>> ls = new ArrayList<ArrayList<Extrusion2D>>(); for (int i = count - 1; i >= 0; i--) { ls.addAll( NativeInset.insetLines( loops, -(i + 0.25) * s.extrusionWidth, ET.shell)); // Negative inset is an outset. } ArrayList<Extrusion3D> output = new ArrayList<Extrusion3D>(); Point3D last = new Point3D(lst.getX(), lst.getY(), z); for (ArrayList<Extrusion2D> br : ls) { Extrusion3D first = lift(br.get(0), z); output.add(new Extrusion3D(last, first.firstPoint(), ET.nonretracting)); for (Extrusion2D ex : br) { output.add(lift(ex, z)); } last = output.get(output.size() - 1).lastPoint(); } return output; }
/** * Computes the radical axis of the two circles. * * @since 0.11.1 * @return the radical axis of the two circles. * @throws IllegalArgumentException if the two circles have same center */ public static StraightLine2D radicalAxis(Circle2D circle1, Circle2D circle2) { // extract center and radius of each circle double r1 = circle1.radius(); double r2 = circle2.radius(); Point2D p1 = circle1.center(); Point2D p2 = circle2.center(); // compute horizontal angle of joining line double angle = Angle2D.horizontalAngle(p1, p2); // distance between centers double dist = p1.distance(p2); if (dist < Shape2D.ACCURACY) { throw new IllegalArgumentException("Input circles must have distinct centers"); } // position of the radical axis on the joining line double d = (dist * dist + r1 * r1 - r2 * r2) * .5 / dist; // pre-compute trigonometric functions double cot = Math.cos(angle); double sit = Math.sin(angle); // compute parameters of the line double x0 = p1.x() + d * cot; double y0 = p1.y() + d * sit; double dx = -sit; double dy = cot; // update state of current line return new StraightLine2D(x0, y0, dx, dy); }
/* * (non-Javadoc) * * @see math.geom2d.Shape2D#transform(math.geom2d.AffineTransform2D) */ public PointArray2D transform(AffineTransform2D trans) { PointArray2D res = new PointArray2D(points.size()); for (Point2D point : points) res.add(point.transform(trans)); return res; }
/** @deprecated replaced by circlesIntersections(Circle2D, Circle2D) (0.11.1) */ @Deprecated public static Collection<Point2D> getIntersections(Circle2D circle1, Circle2D circle2) { ArrayList<Point2D> intersections = new ArrayList<Point2D>(2); // extract center and radius of each circle Point2D center1 = circle1.center(); Point2D center2 = circle2.center(); double r1 = circle1.radius(); double r2 = circle2.radius(); double d = Point2D.distance(center1, center2); // case of no intersection if (d < abs(r1 - r2) || d > (r1 + r2)) return intersections; // Angle of line from center1 to center2 double angle = Angle2D.horizontalAngle(center1, center2); // position of intermediate point double d1 = d / 2 + (r1 * r1 - r2 * r2) / (2 * d); Point2D tmp = Point2D.createPolar(center1, d1, angle); // Add the 2 intersection points double h = sqrt(r1 * r1 - d1 * d1); intersections.add(Point2D.createPolar(tmp, h, angle + PI / 2)); intersections.add(Point2D.createPolar(tmp, h, angle - PI / 2)); return intersections; }
public PointArray2D transform(CircleInversion2D inv) { PointArray2D array = new PointArray2D(points.size()); for (Point2D point : points) array.add(point.transform(inv)); return array; }
/** * Draws the point set on the specified Graphics2D, by filling a disc with a given radius. * * @param g2 the graphics to draw the point set */ public void draw(Graphics2D g2, double r) { double x, y; double w = 2 * r; for (Point2D point : points) { x = point.x(); y = point.y(); g2.fill(new java.awt.geom.Ellipse2D.Double(x - r, y - r, w, w)); } }
/* * (non-Javadoc) * * @see math.geom2d.Shape2D#distance(double, double) */ public double distance(double x, double y) { // basic checkup if (points.isEmpty()) return Double.NaN; // find smallest distance double dist = Double.MAX_VALUE; for (Point2D point : points) dist = Math.min(dist, point.distance(x, y)); // return distance to closest point return dist; }
@Override public String toString() { Point2D center = ellipse.center(); return String.format( Locale.US, "EllipseArc2D(%7.2f,%7.2f,%7.2f,%7.2f,%7.5f,%7.5f,%7.5f)", center.x(), center.y(), ellipse.r1, ellipse.r2, ellipse.theta, startAngle, angleExtent); }
public java.awt.geom.GeneralPath getGeneralPath() { // create new path java.awt.geom.GeneralPath path = new java.awt.geom.GeneralPath(); // move to the first point Point2D point = this.firstPoint(); path.moveTo((float) point.x(), (float) point.y()); // append the curve path = this.appendPath(path); // return the final path return path; }
/** * Transforms this circle by an affine transform. If the transformed shape is a circle (ellipse * with equal axis lengths), returns an instance of Circle2D. The resulting ellipse is direct if * this ellipse and the transform are either both direct or both indirect. */ public EllipseShape2D transform(AffineTransform2D trans) { // When the transform is not a similarity, should switch to EllipseArc // computation if (!AffineTransform2D.isSimilarity(trans)) { return this.asEllipse().transform(trans); } // If transform is a similarity, the result is a circle Point2D center = this.center().transform(trans); Point2D p1 = this.firstPoint().transform(trans); boolean direct = !this.direct ^ trans.isDirect(); Circle2D result = new Circle2D(center, center.distance(p1), direct); return result; }
/* (non-Javadoc) * @see math.geom2d.GeometricObject2D#almostEquals(math.geom2d.GeometricObject2D, double) */ public boolean almostEquals(GeometricObject2D obj, double eps) { if (this == obj) return true; if (!(obj instanceof PointSet2D)) return false; PointSet2D set = (PointSet2D) obj; if (this.points.size() != set.size()) return false; Iterator<Point2D> iter = set.iterator(); for (Point2D point : points) { if (!point.almostEquals(iter.next(), eps)) return false; } return true; }
/** * Returns true if the given object is an instance of PointSet2D that contains the same number of * points, such that iteration on each set returns equal points. */ @Override public boolean equals(Object obj) { if (this == obj) return true; if (!(obj instanceof PointSet2D)) return false; PointSet2D set = (PointSet2D) obj; if (this.points.size() != set.size()) return false; Iterator<Point2D> iter = set.iterator(); for (Point2D point : points) { if (!point.equals(iter.next())) return false; } return true; }
public java.awt.geom.GeneralPath appendPath(java.awt.geom.GeneralPath path) { // number of curves to approximate the arc int nSeg = (int) ceil(abs(angleExtent) / (PI / 2)); nSeg = min(nSeg, 4); // angular extent of each curve double ext = angleExtent / nSeg; // compute coefficient double k = btan(abs(ext)); for (int i = 0; i < nSeg; i++) { // position of the two extremities double ti0 = abs(i * ext); double ti1 = abs((i + 1) * ext); // extremity points Point2D p1 = this.point(ti0); Point2D p2 = this.point(ti1); // tangent vectors, multiplied by appropriate coefficient Vector2D v1 = this.tangent(ti0).times(k); Vector2D v2 = this.tangent(ti1).times(k); // append a cubic curve to the path path.curveTo( p1.x() + v1.x(), p1.y() + v1.y(), p2.x() - v2.x(), p2.y() - v2.y(), p2.x(), p2.y()); } return path; }
/** * Computes intersections of a circle with a line. Returns an array of Point2D, of size 0, 1 or 2 * depending on the distance between circle and line. If there are 2 intersections points, the * first one in the array is the first one on the line. * * @return a collection of intersection points * @since 0.11.1 */ public static Collection<Point2D> lineCircleIntersections( LinearShape2D line, CircularShape2D circle) { // initialize array of points (maximum 2 intersections) ArrayList<Point2D> intersections = new ArrayList<Point2D>(2); // extract parameters of the circle Circle2D parent = circle.supportingCircle(); Point2D center = parent.center(); double radius = parent.radius(); // Compute line perpendicular to the test line, and going through the // circle center StraightLine2D perp = StraightLine2D.createPerpendicular(line, center); // Compute distance between line and circle center Point2D inter = perp.intersection(new StraightLine2D(line)); if (inter == null) { throw new RuntimeException( "Could not compute intersection point when computing line-cicle intersection"); } double dist = inter.distance(center); // if the distance is the radius of the circle, return the // intersection point if (abs(dist - radius) < Shape2D.ACCURACY) { if (line.contains(inter) && circle.contains(inter)) intersections.add(inter); return intersections; } // compute angle of the line, and distance between 'inter' point and // each intersection point double angle = line.horizontalAngle(); double d2 = sqrt(radius * radius - dist * dist); // Compute position and angle of intersection points Point2D p1 = Point2D.createPolar(inter, d2, angle + Math.PI); Point2D p2 = Point2D.createPolar(inter, d2, angle); // add points to the array only if they belong to the line if (line.contains(p1) && circle.contains(p1)) intersections.add(p1); if (line.contains(p2) && circle.contains(p2)) intersections.add(p2); // return the result return intersections; }
public Box2D boundingBox() { // init with max values in each direction double xmin = Double.MAX_VALUE; double ymin = Double.MAX_VALUE; double xmax = Double.MIN_VALUE; double ymax = Double.MIN_VALUE; // update max values with each point for (Point2D point : points) { xmin = Math.min(xmin, point.x()); ymin = Math.min(ymin, point.y()); xmax = Math.max(xmax, point.x()); ymax = Math.max(ymax, point.y()); } // create the bounding box return new Box2D(xmin, xmax, ymin, ymax); }
/** * Computes the circumscribed circle of the 3 input points. * * @return the circle that contains the three input points * @throws ColinearPoints2DException if the 3 points are colinear */ public static Circle2D circumCircle(Point2D p1, Point2D p2, Point2D p3) { // Computes circum center, possibly throwing ColinearPoints2DException Point2D center = circumCenter(p1, p2, p3); // compute radius double radius = Point2D.distance(center, p2); // return the created circle return new Circle2D(center, radius); }
public Polygon scalePolygon(Polygon polygon) { int xs[] = new int[polygon.npoints]; int ys[] = new int[polygon.npoints]; math.geom2d.Point2D p; math.geom2d.Point2D p1; int sumX = 0; int sumY = 0; for (int i = 0; i < polygon.npoints; i++) { p = new math.geom2d.Point2D(polygon.xpoints[i], polygon.ypoints[i]); p1 = p.scale(0.5); sumX += p1.getX(); sumY += p1.getY(); xs[i] = (int) p1.getX(); ys[i] = (int) p1.getY(); p.clone(); } Polygon poly = new Polygon(xs, ys, polygon.npoints); poly.translate(sumX / polygon.npoints, sumY / polygon.npoints); Polygon scalePolygon = new Polygon(); for (int i = 0; i < poly.npoints; i++) { p = new math.geom2d.Point2D(poly.xpoints[i], poly.ypoints[i]); if (i + 1 < poly.npoints) { if (p.distance(poly.xpoints[i + 1], poly.ypoints[i + 1]) > (0.1 * world.getMapWidth())) { scalePolygon.addPoint(poly.xpoints[i], poly.ypoints[i]); } else { continue; } } else if (i + 1 == poly.npoints) { if (p.distance(poly.xpoints[0], poly.ypoints[0]) > (0.1 * world.getMapWidth())) { scalePolygon.addPoint(poly.xpoints[i], poly.ypoints[i]); } else { continue; } } } return scalePolygon; }
/** * Creates a circle containing 3 points. * * @deprecated replaced by createCircle(Point2D, Point2D, Point2D) (0.11.1) */ @Deprecated public static Circle2D create(Point2D p1, Point2D p2, Point2D p3) { if (Point2D.isColinear(p1, p2, p3)) throw new ColinearPoints2DException(p1, p2, p3); // create two median lines StraightLine2D line12 = StraightLine2D.createMedian(p1, p2); StraightLine2D line23 = StraightLine2D.createMedian(p2, p3); // check medians are not parallel assert !AbstractLine2D.isParallel(line12, line23) : "If points are not colinear, medians should not be parallel"; // Compute intersection of the medians, and circle radius Point2D center = AbstractLine2D.getIntersection(line12, line23); double radius = Point2D.distance(center, p2); // return the created circle return new Circle2D(center, radius); }
@Override public void update() { this.defined = false; // check parents are defined if (!parent1.isDefined()) return; if (!parent2.isDefined()) return; Shape2D shape; // extract first point shape = parent1.getShape(); if (!(shape instanceof Point2D)) return; Point2D point1 = (Point2D) shape; // extract second point shape = parent2.getShape(); if (!(shape instanceof Point2D)) return; Point2D point2 = (Point2D) shape; // update distance measure this.trans = AffineTransform2D.createTranslation( point2.getX() - point1.getX(), point2.getY() - point1.getY()); this.defined = true; }
/** * Write streetlight objects in dsf file. * * @param osmPolygon osm road polygon */ public void writeStreetLightToDsf(OsmPolygon osmPolygon) { // init d'un entier pour modulo densité street lights Integer densityIndex = 0; if (XplaneOptionsHelper.getOptions().getLightsDensity() == 0) { densityIndex = 10; } else { if (XplaneOptionsHelper.getOptions().getLightsDensity() == 1) { densityIndex = 5; } else { if (XplaneOptionsHelper.getOptions().getLightsDensity() == 2) densityIndex = 3; } } StringBuffer sb = new StringBuffer(); for (int i = 0; i < osmPolygon.getPolygon().getVertices().size(); i++) { if ((i % densityIndex) == 0) { Point2D lightLoc = osmPolygon.getPolygon().getVertex(i); lightLoc.x = lightLoc.x + 0.0001; lightLoc.y = lightLoc.y + 0.0001; if (GeomUtils.compareCoordinates(lightLoc, currentTile)) { Random randomGenerator = new Random(); int orientation = randomGenerator.nextInt(360); sb.append( "OBJECT " + dsfObjectsProvider.getRandomStreetLightObject() + " " + (lightLoc.y) + " " + (lightLoc.x) + " " + orientation); sb.append(System.getProperty("line.separator")); // stats StatsHelper.addStreetLight(stats); } } } writer.write(sb.toString()); }
/** * Computes the intersections points between two circles or circular shapes. * * @param circle1 an instance of circle or circle arc * @param circle2 an instance of circle or circle arc * @return a collection of 0, 1 or 2 intersection points */ public static Collection<Point2D> circlesIntersections(Circle2D circle1, Circle2D circle2) { // extract center and radius of each circle Point2D center1 = circle1.center(); Point2D center2 = circle2.center(); double r1 = circle1.radius(); double r2 = circle2.radius(); double d = Point2D.distance(center1, center2); // case of no intersection if (d < abs(r1 - r2) || d > (r1 + r2)) return new ArrayList<Point2D>(0); // Angle of line from center1 to center2 double angle = Angle2D.horizontalAngle(center1, center2); if (d == abs(r1 - r2) || d == (r1 + r2)) { Collection<Point2D> r = new ArrayList<>(1); r.add(Point2D.createPolar(center1, r1, angle)); return r; } // position of intermediate point double d1 = d / 2 + (r1 * r1 - r2 * r2) / (2 * d); Point2D tmp = Point2D.createPolar(center1, d1, angle); // distance between intermediate point and each intersection double h = sqrt(r1 * r1 - d1 * d1); // create empty array ArrayList<Point2D> intersections = new ArrayList<Point2D>(2); // Add the 2 intersection points Point2D p1 = Point2D.createPolar(tmp, h, angle + PI / 2); intersections.add(p1); Point2D p2 = Point2D.createPolar(tmp, h, angle - PI / 2); intersections.add(p2); return intersections; }
public Box2D boundingBox() { // first get ending points Point2D p0 = firstPoint(); Point2D p1 = lastPoint(); // get coordinate of ending points double x0 = p0.x(); double y0 = p0.y(); double x1 = p1.x(); double y1 = p1.y(); // initialize min and max coords double xmin = min(x0, x1); double xmax = max(x0, x1); double ymin = min(y0, y1); double ymax = max(y0, y1); // precomputes some values Point2D center = ellipse.center(); double xc = center.x(); double yc = center.y(); double endAngle = startAngle + angleExtent; boolean direct = angleExtent >= 0; // check cases arc contains one maximum if (Angle2D.containsAngle(startAngle, endAngle, PI / 2 + ellipse.theta, direct)) ymax = max(ymax, yc + ellipse.r1); if (Angle2D.containsAngle(startAngle, endAngle, 3 * PI / 2 + ellipse.theta, direct)) ymin = min(ymin, yc - ellipse.r1); if (Angle2D.containsAngle(startAngle, endAngle, ellipse.theta, direct)) xmax = max(xmax, xc + ellipse.r2); if (Angle2D.containsAngle(startAngle, endAngle, PI + ellipse.theta, direct)) xmin = min(xmin, xc - ellipse.r2); // return a bounding with computed limits return new Box2D(xmin, xmax, ymin, ymax); }
/** * This function scales a polygon by the scale coefficient * * @param sourcePolygon : Is the Polygon that we want to scale * @param scale : Is the scale coefficient, It actually multiplies to the points and makes the new * shape * @return : returns the scaled polygon which, its center is on the center of the last polygon */ protected Polygon scalePolygon(Polygon sourcePolygon, double scale) { Polygon scaledPolygon; int xs[] = new int[sourcePolygon.npoints]; int ys[] = new int[sourcePolygon.npoints]; Point2D p, p1; int sumX = 0; int sumY = 0; for (int i = 0; i < sourcePolygon.npoints; i++) { p = new Point2D(sourcePolygon.xpoints[i], sourcePolygon.ypoints[i]); p1 = p.scale(scale); sumX += p1.getX(); sumY += p1.getY(); xs[i] = (int) p1.getX(); ys[i] = (int) p1.getY(); p.clone(); } Polygon preScaledPolygon = new Polygon(xs, ys, sourcePolygon.npoints); scaledPolygon = reAllocatePolygon(preScaledPolygon, sourcePolygon); if (scaledPolygon == null) scaledPolygon = preScaledPolygon; return scaledPolygon; }
/** Returns true if the point p lies on the ellipse, with precision given by Shape2D.ACCURACY. */ public boolean contains(Point2D p) { return contains(p.x(), p.y()); }
public double distance(double x, double y) { return abs(Point2D.distance(xc, yc, x, y) - r); }
public double distance(Point2D point) { return abs(Point2D.distance(xc, yc, point.x(), point.y()) - r); }
public double position(Point2D point) { double angle = Angle2D.horizontalAngle(xc, yc, point.x(), point.y()); if (direct) return Angle2D.formatAngle(angle - theta); else return Angle2D.formatAngle(theta - angle); }
public double signedDistance(double x, double y) { if (direct) return Point2D.distance(xc, yc, x, y) - r; else return r - Point2D.distance(xc, yc, x, y); }
public double signedDistance(Point2D point) { return signedDistance(point.x(), point.y()); }