private LineSegment extractShorelineInterect(SimpleFeature feature) { Object sceObject = ((Double) feature.getAttribute(Constants.SCE_ATTR)); Object nsdObject = feature.getAttribute(Constants.NSD_ATTR); Geometry geometry = (Geometry) feature.getDefaultGeometry(); Coordinate[] coordinates = geometry.getCoordinates(); LineSegment segment = new LineSegment(coordinates[0], coordinates[1]); double length = segment.getLength(); double sce = sceObject instanceof Number ? ((Number) sceObject).doubleValue() : Double.NaN; double nsd = nsdObject instanceof Number ? ((Number) nsdObject).doubleValue() : Double.NaN; if (sce == sce && nsd == nsd) { return extractShorelineInterectAndCheckLength(segment, nsd, sce); } else { if (sce != sce && nsd != nsd) { return extractShorelineInterectAndCheckLength(segment, 0, length); } if (sce != sce) { sce = length - nsd; } else /* if nsd != nsd */ { nsd = length - sce; } return extractShorelineInterectAndCheckLength(segment, nsd, sce); } }
Geometry toShape(List<LineSegment> path, double h) { // TODO: take into account letter alignment // turn the path into a single polygon by generating points orthogonal // to the individual line segments GeomBuilder gb = new GeomBuilder(); LinkedList<Coordinate> top = new LinkedList<Coordinate>(); for (int i = 0; i < path.size(); i++) { LineSegment seg = path.get(i); Coordinate p0 = seg.p0; Coordinate p1 = seg.p1; double theta = seg.angle(); gb.points(p0.x, p0.y); // generate the perpendicular point at a distance of h Coordinate p2 = new Coordinate(); if (theta > 0) { if (theta <= HALFPI) { // ne double phi = Math.PI - (HALFPI + theta); p2.x = (Math.cos(phi) * h - p0.x) * -1; p2.y = Math.sin(phi) * h + p0.y; } else { // nw double phi = Math.PI - theta; p2.x = Math.cos(phi) * h + p0.x; p2.y = Math.sin(phi) * h + p0.y; } } else { theta = Math.abs(theta); if (theta < HALFPI) { double phi = HALFPI - theta; p2.x = (Math.cos(phi) * h + p0.x); p2.y = (Math.sin(phi) * h + p0.y); } else { double phi = theta = HALFPI; p2.x = Math.cos(phi) * h + p0.x; p2.y = (Math.sin(phi) * h - p0.y) * -1; } } top.add(p2); if (i == path.size() - 1) { gb.points(p1.x, p1.y); top.add(new Coordinate(p1.x + p2.x - p0.x, p1.y + p2.y - p0.y)); } } for (Iterator<Coordinate> it = top.descendingIterator(); it.hasNext(); ) { Coordinate c = it.next(); gb.points(c.x, c.y); } return gb.toPolygon(); }
@Override public boolean intersects(Rectangle r) { GeometryFactory gf = new GeometryFactory(); GeometricShapeFactory f = new GeometricShapeFactory(gf); f.setBase(new Coordinate(r.x1(), r.y1())); f.setWidth(r.x2() - r.x1()); f.setHeight(r.y2() - r.y1()); Polygon rect = f.createRectangle(); LineSegment line = new LineSegment(x1, y1, x2, y2); return RectangleIntersects.intersects(rect, line.toGeometry(gf)); }
public void pushSegment(final LineSegment segment) { final double length = segment.getLength(); /* update station of segment points */ m_length1 = m_length2; m_length2 = m_length1 + length; /* update distance at station */ // REMARK: NaN check needed for very first segment m_distance1 = Double.isNaN(m_distance2) ? m_bufferBuilder.getDistance(m_length1) : m_distance2; m_distance2 = m_bufferBuilder.getDistance(m_length2); /* * Only push the segment, if length is greater than the tolerance, the distance is always updated however, in order * to keep the correct stationing of the line */ if (length > m_tolerance) { m_segment0 = m_segment1; m_segment1 = segment; m_buffer0 = m_buffer1; m_buffer1 = calculateBuffer(m_segment1, m_distance1, m_distance2); } addBufferCoordinates(); }
/** * Computes the closest points on two line segments. * * @param line the segment to find the closest point to * @return a pair of Coordinates which are the closest points on the line segments */ public Coordinate[] closestPoints(LineSegment line) { // test for intersection Coordinate intPt = intersection(line); if (intPt != null) { return new Coordinate[] {intPt, intPt}; } /** * if no intersection closest pair contains at least one endpoint. Test each endpoint in turn. */ Coordinate[] closestPt = new Coordinate[2]; double minDistance = Double.MAX_VALUE; double dist; Coordinate close00 = closestPoint(line.p0); minDistance = close00.distance(line.p0); closestPt[0] = close00; closestPt[1] = line.p0; Coordinate close01 = closestPoint(line.p1); dist = close01.distance(line.p1); if (dist < minDistance) { minDistance = dist; closestPt[0] = close01; closestPt[1] = line.p1; } Coordinate close10 = line.closestPoint(p0); dist = close10.distance(p0); if (dist < minDistance) { minDistance = dist; closestPt[0] = p0; closestPt[1] = close10; } Coordinate close11 = line.closestPoint(p1); dist = close11.distance(p1); if (dist < minDistance) { minDistance = dist; closestPt[0] = p1; closestPt[1] = close11; } return closestPt; }
/** * Adds a limited mitre join connecting the two reflex offset segments. A limited mitre is a mitre * which is beveled at the distance determined by the mitre ratio limit. * * @param offset0 the first offset segment * @param offset1 the second offset segment * @param distance the offset distance * @param mitreLimit the mitre limit ratio */ private void addLimitedMitreJoin(final double distance, final double mitreLimit) { final Coordinate basePt = m_segment0.p1; final double ang0 = Angle.angle(basePt, m_segment0.p0); // oriented angle between segments final double angDiff = Angle.angleBetweenOriented(m_segment0.p0, basePt, m_segment1.p1); // half of the interior angle final double angDiffHalf = angDiff / 2; // angle for bisector of the interior angle between the segments final double midAng = Angle.normalize(ang0 + angDiffHalf); // rotating this by PI gives the bisector of the reflex angle final double mitreMidAng = Angle.normalize(midAng + Math.PI); // the miterLimit determines the distance to the mitre bevel final double mitreDist = mitreLimit * distance; // the bevel delta is the difference between the buffer distance // and half of the length of the bevel segment final double bevelDelta = mitreDist * Math.abs(Math.sin(angDiffHalf)); final double bevelHalfLen = distance - bevelDelta; // compute the midpoint of the bevel segment final double bevelMidX = basePt.x + mitreDist * Math.cos(mitreMidAng); final double bevelMidY = basePt.y + mitreDist * Math.sin(mitreMidAng); final Coordinate bevelMidPt = new Coordinate(bevelMidX, bevelMidY); // compute the mitre midline segment from the corner point to the bevel segment midpoint final LineSegment mitreMidLine = new LineSegment(basePt, bevelMidPt); // finally the bevel segment endpoints are computed as offsets from // the mitre midline final Coordinate bevelEndLeft = mitreMidLine.pointAlongOffset(1.0, bevelHalfLen); final Coordinate bevelEndRight = mitreMidLine.pointAlongOffset(1.0, -bevelHalfLen); if (m_side == Position.LEFT) { m_bufferBuilder.addVertices(bevelEndLeft); m_bufferBuilder.addVertices(bevelEndRight); } else { m_bufferBuilder.addVertices(bevelEndRight); m_bufferBuilder.addVertices(bevelEndLeft); } }
public void run(IProgressMonitor monitor) throws Exception { final ILayer editLayer = handler.getEditLayer(); final Point mouseLocation = position; final EditBlackboard layerBlackboard = handler.getEditBlackboard(editLayer); final boolean includeSegmentsInCurrent = true; final SnapBehaviour snapBehaviour = SnapBehaviour.CURRENT_LAYER; final CoordinateReferenceSystem mapCrs = handler.getContext().getCRS(); final int snappingRadius = PreferenceUtil.instance().getSnappingRadius(); final SnapSegmentFinder segmentFinder = new SnapSegmentFinder(mapCrs); List<LineSegment> linesList = new ArrayList<LineSegment>(); LineSegment closestSnapSegment; closestSnapSegment = segmentFinder.getClosestSnapSegment( handler, layerBlackboard, mouseLocation, includeSegmentsInCurrent, snapBehaviour, snappingRadius); if (closestSnapSegment != null) { CoordinateReferenceSystem layerCrs = editLayer.getCRS(); closestSnapSegment = GeoToolsUtils.reproject(closestSnapSegment, mapCrs, layerCrs); } linesList.add(closestSnapSegment); if (this.mapMouseEvent.isShiftDown()) { this.segmentCopyContext.addSegments(linesList); } else { this.segmentCopyContext.setReferenceLineSegment(closestSnapSegment); } this.segmentCopyContext.setMode(PrecisionToolsMode.WAITING); System.out.println("\nSegment: " + closestSnapSegment.toString()); }
private void simplifySection(int i, int j) { if ((i + 1) == j) { return; } seg.p0 = pts[i]; seg.p1 = pts[j]; double maxDistance = -1.0; int maxIndex = i; for (int k = i + 1; k < j; k++) { double distance = seg.distance(pts[k]); if (distance > maxDistance) { maxDistance = distance; maxIndex = k; } } if (maxDistance <= distanceTolerance) { for (int k = i + 1; k < j; k++) { usePt[k] = false; } } else { simplifySection(i, maxIndex); simplifySection(maxIndex, j); } }
private LineSegment extractShorelineInterectAndCheckLength( LineSegment transect, double nsd, double sce) { double tl = transect.getLength(); LineSegment shorelineIntersect = new LineSegment(transect.pointAlong(nsd / tl), transect.pointAlong((nsd + sce) / tl)); double shorelineIntersectLength = shorelineIntersect.getLength(); if (minimumLengthMeters > 0 && shorelineIntersectLength < minimumLengthMeters) { double halfRatio = (minimumLengthMeters / shorelineIntersectLength) / 2; shorelineIntersect = new LineSegment( shorelineIntersect.pointAlong(0 - halfRatio), shorelineIntersect.pointAlong(1 + halfRatio)); } return shorelineIntersect; }
/* * (non-Javadoc) * * @see com.iver.cit.gvsig.gui.cad.snapping.ISnapper#getSnapPoint(Point2D * point, IGeometry geom,double tolerance, Point2D lastPointEntered) */ public Point2D getSnapPoint( Point2D point, IGeometry geom, double tolerance, Point2D lastPointEntered) { Point2D resul = null; Coordinate c = new Coordinate(point.getX(), point.getY()); if (lastPointEntered == null) { return null; } Coordinate cLastPoint = new Coordinate(lastPointEntered.getX(), lastPointEntered.getY()); PathIterator theIterator = geom.getPathIterator(null, FConverter.FLATNESS); // polyLine.getPathIterator(null, // flatness); double[] theData = new double[6]; double minDist = tolerance; Coordinate from = null; Coordinate first = null; while (!theIterator.isDone()) { // while not done int theType = theIterator.currentSegment(theData); switch (theType) { case PathIterator.SEG_MOVETO: from = new Coordinate(theData[0], theData[1]); first = from; break; case PathIterator.SEG_LINETO: // System.out.println("SEG_LINETO"); Coordinate to = new Coordinate(theData[0], theData[1]); LineSegment line = new LineSegment(from, to); Coordinate closestPoint = line.closestPoint(cLastPoint); double dist = c.distance(closestPoint); if (!(line.getCoordinate(0).equals2D(closestPoint) || line.getCoordinate(1).equals2D(closestPoint))) { if ((dist < minDist)) { resul = new Point2D.Double(closestPoint.x, closestPoint.y); minDist = dist; } } from = to; break; case PathIterator.SEG_CLOSE: line = new LineSegment(from, first); closestPoint = line.closestPoint(cLastPoint); dist = c.distance(closestPoint); if (!(line.getCoordinate(0).equals2D(closestPoint) || line.getCoordinate(1).equals2D(closestPoint))) { if ((dist < minDist)) { resul = new Point2D.Double(closestPoint.x, closestPoint.y); minDist = dist; } } from = first; break; } // end switch theIterator.next(); } return resul; }
public void select(LineSegment ls) { rcc.countSegment(ls.getCoordinate(0), ls.getCoordinate(1)); }
public void visitItem(Object item) { LineSegment seg = (LineSegment) item; counter.countSegment(seg.getCoordinate(0), seg.getCoordinate(1)); }