jsts-rails 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/lib/jsts-rails/version.rb +1 -1
- data/vendor/assets/javascripts/javascript.util.js +33 -1
- data/vendor/assets/javascripts/jsts-original.js +164 -1573
- data/vendor/assets/javascripts/jsts.js +197 -0
- data/vendor/assets/javascripts/jsts/algorithm/Angle.js +387 -0
- data/vendor/assets/javascripts/jsts/algorithm/BoundaryNodeRule.js +67 -0
- data/vendor/assets/javascripts/jsts/algorithm/CGAlgorithms.js +596 -0
- data/vendor/assets/javascripts/jsts/algorithm/CentralEndpointIntersector.js +118 -0
- data/vendor/assets/javascripts/jsts/algorithm/CentroidArea.js +225 -0
- data/vendor/assets/javascripts/jsts/algorithm/CentroidLine.js +85 -0
- data/vendor/assets/javascripts/jsts/algorithm/CentroidPoint.js +77 -0
- data/vendor/assets/javascripts/jsts/algorithm/ConvexHull.js +409 -0
- data/vendor/assets/javascripts/jsts/algorithm/HCoordinate.js +234 -0
- data/vendor/assets/javascripts/jsts/algorithm/LineIntersector.js +502 -0
- data/vendor/assets/javascripts/jsts/algorithm/MCPointInRing.js +124 -0
- data/vendor/assets/javascripts/jsts/algorithm/PointLocator.js +247 -0
- data/vendor/assets/javascripts/jsts/algorithm/RayCrossingCounter.js +215 -0
- data/vendor/assets/javascripts/jsts/algorithm/RobustDeterminant.js +353 -0
- data/vendor/assets/javascripts/jsts/algorithm/RobustLineIntersector.js +477 -0
- data/vendor/assets/javascripts/jsts/algorithm/distance/DiscreteHausdorffDistance.js +228 -0
- data/vendor/assets/javascripts/jsts/algorithm/distance/DistanceToPoint.js +68 -0
- data/vendor/assets/javascripts/jsts/algorithm/distance/PointPairDistance.js +104 -0
- data/vendor/assets/javascripts/jsts/algorithm/locate/PointOnGeometryLocator.js +7 -0
- data/vendor/assets/javascripts/jsts/algorithm/locate/SimplePointInAreaLocator.js +102 -0
- data/vendor/assets/javascripts/jsts/geom/Coordinate.js +158 -0
- data/vendor/assets/javascripts/jsts/geom/CoordinateArrays.js +148 -0
- data/vendor/assets/javascripts/jsts/geom/CoordinateFilter.js +29 -0
- data/vendor/assets/javascripts/jsts/geom/CoordinateList.js +157 -0
- data/vendor/assets/javascripts/jsts/geom/CoordinateSequenceFilter.js +63 -0
- data/vendor/assets/javascripts/jsts/geom/Dimension.js +137 -0
- data/vendor/assets/javascripts/jsts/geom/Envelope.js +833 -0
- data/vendor/assets/javascripts/jsts/geom/Geometry.js +1535 -0
- data/vendor/assets/javascripts/jsts/geom/GeometryCollection.js +230 -0
- data/vendor/assets/javascripts/jsts/geom/GeometryComponentFilter.js +36 -0
- data/vendor/assets/javascripts/jsts/geom/GeometryFactory.js +263 -0
- data/vendor/assets/javascripts/jsts/geom/GeometryFilter.js +29 -0
- data/vendor/assets/javascripts/jsts/geom/IntersectionMatrix.js +650 -0
- data/vendor/assets/javascripts/jsts/geom/LineSegment.js +275 -0
- data/vendor/assets/javascripts/jsts/geom/LineString.js +299 -0
- data/vendor/assets/javascripts/jsts/geom/LinearRing.js +69 -0
- data/vendor/assets/javascripts/jsts/geom/Location.js +83 -0
- data/vendor/assets/javascripts/jsts/geom/MultiLineString.js +47 -0
- data/vendor/assets/javascripts/jsts/geom/MultiPoint.js +64 -0
- data/vendor/assets/javascripts/jsts/geom/MultiPolygon.js +64 -0
- data/vendor/assets/javascripts/jsts/geom/Point.js +197 -0
- data/vendor/assets/javascripts/jsts/geom/Polygon.js +263 -0
- data/vendor/assets/javascripts/jsts/geom/PrecisionModel.js +187 -0
- data/vendor/assets/javascripts/jsts/geom/Triangle.js +313 -0
- data/vendor/assets/javascripts/jsts/geom/util/GeometryCombiner.js +143 -0
- data/vendor/assets/javascripts/jsts/geom/util/GeometryExtracter.js +76 -0
- data/vendor/assets/javascripts/jsts/geom/util/GeometryTransformer.js +295 -0
- data/vendor/assets/javascripts/jsts/geom/util/LinearComponentExtracter.js +207 -0
- data/vendor/assets/javascripts/jsts/geom/util/PointExtracter.js +67 -0
- data/vendor/assets/javascripts/jsts/geom/util/PolygonExtracter.js +71 -0
- data/vendor/assets/javascripts/jsts/geomgraph/Depth.js +145 -0
- data/vendor/assets/javascripts/jsts/geomgraph/DirectedEdge.js +270 -0
- data/vendor/assets/javascripts/jsts/geomgraph/DirectedEdgeStar.js +388 -0
- data/vendor/assets/javascripts/jsts/geomgraph/Edge.js +291 -0
- data/vendor/assets/javascripts/jsts/geomgraph/EdgeEnd.js +188 -0
- data/vendor/assets/javascripts/jsts/geomgraph/EdgeEndStar.js +322 -0
- data/vendor/assets/javascripts/jsts/geomgraph/EdgeIntersection.js +122 -0
- data/vendor/assets/javascripts/jsts/geomgraph/EdgeIntersectionList.js +146 -0
- data/vendor/assets/javascripts/jsts/geomgraph/EdgeList.js +111 -0
- data/vendor/assets/javascripts/jsts/geomgraph/EdgeNodingValidator.js +76 -0
- data/vendor/assets/javascripts/jsts/geomgraph/EdgeRing.js +230 -0
- data/vendor/assets/javascripts/jsts/geomgraph/GeometryGraph.js +469 -0
- data/vendor/assets/javascripts/jsts/geomgraph/GraphComponent.js +181 -0
- data/vendor/assets/javascripts/jsts/geomgraph/Label.js +316 -0
- data/vendor/assets/javascripts/jsts/geomgraph/Node.js +105 -0
- data/vendor/assets/javascripts/jsts/geomgraph/NodeFactory.js +22 -0
- data/vendor/assets/javascripts/jsts/geomgraph/NodeMap.js +128 -0
- data/vendor/assets/javascripts/jsts/geomgraph/PlanarGraph.js +214 -0
- data/vendor/assets/javascripts/jsts/geomgraph/Position.js +63 -0
- data/vendor/assets/javascripts/jsts/geomgraph/Quadrant.js +143 -0
- data/vendor/assets/javascripts/jsts/geomgraph/TopologyLocation.js +251 -0
- data/vendor/assets/javascripts/jsts/geomgraph/index/EdgeSetIntersector.js +47 -0
- data/vendor/assets/javascripts/jsts/geomgraph/index/SegmentIntersector.js +298 -0
- data/vendor/assets/javascripts/jsts/geomgraph/index/SimpleEdgeSetIntersector.js +107 -0
- data/vendor/assets/javascripts/jsts/geomgraph/index/SimpleMCSweepLineIntersector.js +29 -0
- data/vendor/assets/javascripts/jsts/index/ArrayListVisitor.js +37 -0
- data/vendor/assets/javascripts/jsts/index/DoubleBits.js +132 -0
- data/vendor/assets/javascripts/jsts/index/IntervalSize.js +55 -0
- data/vendor/assets/javascripts/jsts/index/ItemVisitor.js +23 -0
- data/vendor/assets/javascripts/jsts/index/SpatialIndex.js +67 -0
- data/vendor/assets/javascripts/jsts/index/bintree/Bintree.js +224 -0
- data/vendor/assets/javascripts/jsts/index/bintree/Interval.js +160 -0
- data/vendor/assets/javascripts/jsts/index/bintree/Key.js +110 -0
- data/vendor/assets/javascripts/jsts/index/bintree/Node.js +204 -0
- data/vendor/assets/javascripts/jsts/index/bintree/NodeBase.js +220 -0
- data/vendor/assets/javascripts/jsts/index/bintree/Root.js +113 -0
- data/vendor/assets/javascripts/jsts/index/chain/MonotoneChain.js +244 -0
- data/vendor/assets/javascripts/jsts/index/chain/MonotoneChainBuilder.js +106 -0
- data/vendor/assets/javascripts/jsts/index/chain/MonotoneChainOverlapAction.js +56 -0
- data/vendor/assets/javascripts/jsts/index/chain/MonotoneChainSelectAction.js +44 -0
- data/vendor/assets/javascripts/jsts/index/kdtree/KdNode.js +171 -0
- data/vendor/assets/javascripts/jsts/index/kdtree/KdTree.js +218 -0
- data/vendor/assets/javascripts/jsts/index/quadtree/Key.js +134 -0
- data/vendor/assets/javascripts/jsts/index/quadtree/Node.js +220 -0
- data/vendor/assets/javascripts/jsts/index/quadtree/NodeBase.js +330 -0
- data/vendor/assets/javascripts/jsts/index/quadtree/Quadtree.js +228 -0
- data/vendor/assets/javascripts/jsts/index/quadtree/Root.js +105 -0
- data/vendor/assets/javascripts/jsts/index/strtree/AbstractNode.js +107 -0
- data/vendor/assets/javascripts/jsts/index/strtree/AbstractSTRtree.js +594 -0
- data/vendor/assets/javascripts/jsts/index/strtree/Boundable.js +37 -0
- data/vendor/assets/javascripts/jsts/index/strtree/BoundablePair.js +0 -0
- data/vendor/assets/javascripts/jsts/index/strtree/Interval.js +94 -0
- data/vendor/assets/javascripts/jsts/index/strtree/ItemBoundable.js +60 -0
- data/vendor/assets/javascripts/jsts/index/strtree/SIRtree.js +122 -0
- data/vendor/assets/javascripts/jsts/index/strtree/STRtree.js +450 -0
- data/vendor/assets/javascripts/jsts/io/GeoJSONParser.js +471 -0
- data/vendor/assets/javascripts/jsts/io/GeoJSONReader.js +58 -0
- data/vendor/assets/javascripts/jsts/io/GeoJSONWriter.js +38 -0
- data/vendor/assets/javascripts/jsts/io/OpenLayersParser.js +245 -0
- data/vendor/assets/javascripts/jsts/io/WKTParser.js +421 -0
- data/vendor/assets/javascripts/jsts/io/WKTReader.js +68 -0
- data/vendor/assets/javascripts/jsts/io/WKTWriter.js +61 -0
- data/vendor/assets/javascripts/jsts/noding/BasicSegmentString.js +87 -0
- data/vendor/assets/javascripts/jsts/noding/FastNodingValidator.js +127 -0
- data/vendor/assets/javascripts/jsts/noding/InteriorIntersectionFinder.js +171 -0
- data/vendor/assets/javascripts/jsts/noding/IntersectionAdder.js +198 -0
- data/vendor/assets/javascripts/jsts/noding/IntersectionFinderAdder.js +79 -0
- data/vendor/assets/javascripts/jsts/noding/MCIndexNoder.js +147 -0
- data/vendor/assets/javascripts/jsts/noding/NodableSegmentString.js +35 -0
- data/vendor/assets/javascripts/jsts/noding/NodedSegmentString.js +235 -0
- data/vendor/assets/javascripts/jsts/noding/Noder.js +41 -0
- data/vendor/assets/javascripts/jsts/noding/NodingValidator.js +5 -0
- data/vendor/assets/javascripts/jsts/noding/Octant.js +84 -0
- data/vendor/assets/javascripts/jsts/noding/OrientedCoordinateArray.js +94 -0
- data/vendor/assets/javascripts/jsts/noding/ScaledNoder.js +105 -0
- data/vendor/assets/javascripts/jsts/noding/SegmentIntersector.js +45 -0
- data/vendor/assets/javascripts/jsts/noding/SegmentNode.js +70 -0
- data/vendor/assets/javascripts/jsts/noding/SegmentNodeList.js +262 -0
- data/vendor/assets/javascripts/jsts/noding/SegmentPointComparator.js +78 -0
- data/vendor/assets/javascripts/jsts/noding/SegmentString.js +61 -0
- data/vendor/assets/javascripts/jsts/noding/SinglePassNoder.js +51 -0
- data/vendor/assets/javascripts/jsts/noding/snapround/HotPixel.js +271 -0
- data/vendor/assets/javascripts/jsts/noding/snapround/MCIndexPointSnapper.js +96 -0
- data/vendor/assets/javascripts/jsts/noding/snapround/MCIndexSnapRounder.js +147 -0
- data/vendor/assets/javascripts/jsts/operation/BoundaryOp.js +166 -0
- data/vendor/assets/javascripts/jsts/operation/GeometryGraphOperation.js +90 -0
- data/vendor/assets/javascripts/jsts/operation/IsSimpleOp.js +293 -0
- data/vendor/assets/javascripts/jsts/operation/buffer/BufferBuilder.js +317 -0
- data/vendor/assets/javascripts/jsts/operation/buffer/BufferInputLineSimplifier.js +294 -0
- data/vendor/assets/javascripts/jsts/operation/buffer/BufferOp.js +340 -0
- data/vendor/assets/javascripts/jsts/operation/buffer/BufferParameters.js +328 -0
- data/vendor/assets/javascripts/jsts/operation/buffer/BufferSubgraph.js +296 -0
- data/vendor/assets/javascripts/jsts/operation/buffer/OffsetCurveBuilder.js +369 -0
- data/vendor/assets/javascripts/jsts/operation/buffer/OffsetCurveSetBuilder.js +301 -0
- data/vendor/assets/javascripts/jsts/operation/buffer/OffsetSegmentGenerator.js +777 -0
- data/vendor/assets/javascripts/jsts/operation/buffer/OffsetSegmentString.js +109 -0
- data/vendor/assets/javascripts/jsts/operation/buffer/RightmostEdgeFinder.js +164 -0
- data/vendor/assets/javascripts/jsts/operation/buffer/SubgraphDepthLocater.js +220 -0
- data/vendor/assets/javascripts/jsts/operation/distance/ConnectedElementLocationFilter.js +67 -0
- data/vendor/assets/javascripts/jsts/operation/distance/DistanceOp.js +506 -0
- data/vendor/assets/javascripts/jsts/operation/distance/GeometryLocation.js +102 -0
- data/vendor/assets/javascripts/jsts/operation/overlay/LineBuilder.js +194 -0
- data/vendor/assets/javascripts/jsts/operation/overlay/MaximalEdgeRing.js +72 -0
- data/vendor/assets/javascripts/jsts/operation/overlay/MinimalEdgeRing.js +33 -0
- data/vendor/assets/javascripts/jsts/operation/overlay/OverlayNodeFactory.js +26 -0
- data/vendor/assets/javascripts/jsts/operation/overlay/OverlayOp.js +584 -0
- data/vendor/assets/javascripts/jsts/operation/overlay/PointBuilder.js +103 -0
- data/vendor/assets/javascripts/jsts/operation/overlay/PolygonBuilder.js +282 -0
- data/vendor/assets/javascripts/jsts/operation/overlay/snap/GeometrySnapper.js +228 -0
- data/vendor/assets/javascripts/jsts/operation/overlay/snap/LineStringSnapper.js +228 -0
- data/vendor/assets/javascripts/jsts/operation/overlay/snap/SnapIfNeededOverlayOp.js +85 -0
- data/vendor/assets/javascripts/jsts/operation/overlay/snap/SnapOverlayOp.js +134 -0
- data/vendor/assets/javascripts/jsts/operation/polygonize/EdgeRing.js +259 -0
- data/vendor/assets/javascripts/jsts/operation/polygonize/PolygonizeDirectedEdge.js +94 -0
- data/vendor/assets/javascripts/jsts/operation/polygonize/PolygonizeEdge.js +31 -0
- data/vendor/assets/javascripts/jsts/operation/polygonize/PolygonizeGraph.js +507 -0
- data/vendor/assets/javascripts/jsts/operation/polygonize/Polygonizer.js +259 -0
- data/vendor/assets/javascripts/jsts/operation/relate/EdgeEndBuilder.js +140 -0
- data/vendor/assets/javascripts/jsts/operation/relate/EdgeEndBundle.js +183 -0
- data/vendor/assets/javascripts/jsts/operation/relate/EdgeEndBundleStar.js +48 -0
- data/vendor/assets/javascripts/jsts/operation/relate/RelateComputer.js +444 -0
- data/vendor/assets/javascripts/jsts/operation/relate/RelateNode.js +46 -0
- data/vendor/assets/javascripts/jsts/operation/relate/RelateNodeFactory.js +25 -0
- data/vendor/assets/javascripts/jsts/operation/relate/RelateNodeGraph.js +118 -0
- data/vendor/assets/javascripts/jsts/operation/relate/RelateOp.js +75 -0
- data/vendor/assets/javascripts/jsts/operation/union/CascadedPolygonUnion.js +319 -0
- data/vendor/assets/javascripts/jsts/operation/union/PointGeometryUnion.js +118 -0
- data/vendor/assets/javascripts/jsts/operation/union/UnaryUnionOp.js +244 -0
- data/vendor/assets/javascripts/jsts/operation/union/UnionInteracting.js +156 -0
- data/vendor/assets/javascripts/jsts/operation/valid/ConnectedInteriorTester.js +259 -0
- data/vendor/assets/javascripts/jsts/operation/valid/ConsistentAreaTester.js +127 -0
- data/vendor/assets/javascripts/jsts/operation/valid/IndexedNestedRingTester.js +89 -0
- data/vendor/assets/javascripts/jsts/operation/valid/IsValidOp.js +619 -0
- data/vendor/assets/javascripts/jsts/operation/valid/TopologyValidationError.js +199 -0
- data/vendor/assets/javascripts/jsts/planargraph/DirectedEdge.js +232 -0
- data/vendor/assets/javascripts/jsts/planargraph/DirectedEdgeStar.js +168 -0
- data/vendor/assets/javascripts/jsts/planargraph/Edge.js +124 -0
- data/vendor/assets/javascripts/jsts/planargraph/GraphComponent.js +182 -0
- data/vendor/assets/javascripts/jsts/planargraph/Node.js +127 -0
- data/vendor/assets/javascripts/jsts/planargraph/NodeMap.js +76 -0
- data/vendor/assets/javascripts/jsts/planargraph/PlanarGraph.js +246 -0
- data/vendor/assets/javascripts/jsts/simplify/LineSegmentIndex.js +101 -0
- data/vendor/assets/javascripts/jsts/triangulate/DelaunayTriangulationBuilder.js +224 -0
- data/vendor/assets/javascripts/jsts/triangulate/IncrementalDelaunayTriangulator.js +111 -0
- data/vendor/assets/javascripts/jsts/triangulate/VoronoiDiagramBuilder.js +172 -0
- data/vendor/assets/javascripts/jsts/triangulate/quadedge/LastFoundQuadEdgeLocator.js +52 -0
- data/vendor/assets/javascripts/jsts/triangulate/quadedge/QuadEdge.js +437 -0
- data/vendor/assets/javascripts/jsts/triangulate/quadedge/QuadEdgeSubdivision.js +1064 -0
- data/vendor/assets/javascripts/jsts/triangulate/quadedge/TrianglePredicate.js +350 -0
- data/vendor/assets/javascripts/jsts/triangulate/quadedge/Vertex.js +496 -0
- data/vendor/assets/javascripts/jsts/util/Assert.js +80 -0
- data/vendor/assets/javascripts/jsts/util/AssertionFailedException.js +23 -0
- data/vendor/assets/javascripts/jsts/util/UniqueCoordinateArrayFilter.js +52 -0
- metadata +204 -1
@@ -0,0 +1,1064 @@
|
|
1
|
+
/* Copyright (c) 2011 by The Authors.
|
2
|
+
* Published under the LGPL 2.1 license.
|
3
|
+
* See /license-notice.txt for the full text of the license notice.
|
4
|
+
* See /license.txt for the full text of the license.
|
5
|
+
*/
|
6
|
+
|
7
|
+
/**
|
8
|
+
* @requires jsts/io/WKTWriter.js
|
9
|
+
*/
|
10
|
+
|
11
|
+
/**
|
12
|
+
* A class that contains the {@link QuadEdge}s representing a planar
|
13
|
+
* subdivision that models a triangulation.
|
14
|
+
* The subdivision is constructed using the
|
15
|
+
* quadedge algebra defined in the classs {@link QuadEdge}.
|
16
|
+
* All metric calculations
|
17
|
+
* are done in the {@link Vertex} class.
|
18
|
+
* In addition to a triangulation, subdivisions
|
19
|
+
* support extraction of Voronoi diagrams.
|
20
|
+
* This is easily accomplished, since the Voronoi diagram is the dual
|
21
|
+
* of the Delaunay triangulation.
|
22
|
+
* <p>
|
23
|
+
* Subdivisions can be provided with a tolerance value. Inserted vertices which
|
24
|
+
* are closer than this value to vertices already in the subdivision will be
|
25
|
+
* ignored. Using a suitable tolerance value can prevent robustness failures
|
26
|
+
* from happening during Delaunay triangulation.
|
27
|
+
* <p>
|
28
|
+
* Subdivisions maintain a <b>frame</b> triangle around the client-created
|
29
|
+
* edges. The frame is used to provide a bounded "container" for all edges
|
30
|
+
* within a TIN. Normally the frame edges, frame connecting edges, and frame
|
31
|
+
* triangles are not included in client processing.
|
32
|
+
*
|
33
|
+
* @author David Skea
|
34
|
+
* @author Martin Davis
|
35
|
+
*/
|
36
|
+
|
37
|
+
/**
|
38
|
+
* Creates a new instance of a quad-edge subdivision based on a frame triangle
|
39
|
+
* that encloses a supplied bounding box. A new super-bounding box that contains
|
40
|
+
* the triangle is computed and stored.
|
41
|
+
*
|
42
|
+
* @param env
|
43
|
+
* the bouding box to surround.
|
44
|
+
* @param tolerance
|
45
|
+
* the tolerance value for determining if two sites are equal.
|
46
|
+
*
|
47
|
+
* @constructor
|
48
|
+
*/
|
49
|
+
jsts.triangulate.quadedge.QuadEdgeSubdivision = function(env, tolerance) {
|
50
|
+
this.tolerance = tolerance;
|
51
|
+
this.edgeCoincidenceTolerance = tolerance / jsts.triangulate.quadedge.QuadEdgeSubdivision.EDGE_COINCIDENCE_TOL_FACTOR;
|
52
|
+
|
53
|
+
//used for edge extraction to ensure edge uniqueness
|
54
|
+
this.visitedKey = 0;
|
55
|
+
this.quadEdges = [];
|
56
|
+
this.startingEdge;
|
57
|
+
this.tolerance;
|
58
|
+
this.edgeCoincidenceTolerance;
|
59
|
+
this.frameEnv;
|
60
|
+
this.locator = null;
|
61
|
+
this.seg = new jsts.geom.LineSegment();
|
62
|
+
this.triEdges = new Array(3);
|
63
|
+
this.frameVertex = new Array(3);
|
64
|
+
this.createFrame(env);
|
65
|
+
|
66
|
+
this.startingEdge = this.initSubdiv();
|
67
|
+
this.locator = new jsts.triangulate.quadedge.LastFoundQuadEdgeLocator(this);
|
68
|
+
};
|
69
|
+
|
70
|
+
jsts.triangulate.quadedge.QuadEdgeSubdivision.EDGE_COINCIDENCE_TOL_FACTOR = 1000;
|
71
|
+
|
72
|
+
/**
|
73
|
+
* Gets the edges for the triangle to the left of the given {@link QuadEdge}.
|
74
|
+
*
|
75
|
+
* @param {jsts.triangulate.quadedge.QuadEdge}
|
76
|
+
* startQE the starting quad-edge.
|
77
|
+
* @param {jsts.triangulate.quadedge.QuadEdge[]}
|
78
|
+
* triEdge array of quadedges.
|
79
|
+
*
|
80
|
+
* @throws IllegalArgumentException
|
81
|
+
* if the edges do not form a triangle
|
82
|
+
*/
|
83
|
+
jsts.triangulate.quadedge.QuadEdgeSubdivision.getTriangleEdges = function(startQE, triEdge) {
|
84
|
+
triEdge[0] = startQE;
|
85
|
+
triEdge[1] = triEdge[0].lNext();
|
86
|
+
triEdge[2] = triEdge[1].lNext();
|
87
|
+
if (triEdge[2].lNext() != triEdge[0]) {
|
88
|
+
throw new jsts.IllegalArgumentError('Edges do not form a triangle');
|
89
|
+
}
|
90
|
+
};
|
91
|
+
|
92
|
+
/**
|
93
|
+
* Creates the framing envelope
|
94
|
+
*
|
95
|
+
* @param {jsts.geom.Envelope}
|
96
|
+
* env an envelope.
|
97
|
+
*/
|
98
|
+
jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.createFrame = function(env) {
|
99
|
+
var deltaX, deltaY, offset;
|
100
|
+
|
101
|
+
deltaX = env.getWidth();
|
102
|
+
deltaY = env.getHeight();
|
103
|
+
offset = 0.0;
|
104
|
+
|
105
|
+
if (deltaX > deltaY) {
|
106
|
+
offset = deltaX * 10.0;
|
107
|
+
}else {
|
108
|
+
offset = deltaY * 10.0;
|
109
|
+
}
|
110
|
+
|
111
|
+
this.frameVertex[0] = new jsts.triangulate.quadedge.Vertex((env.getMaxX() + env.getMinX()) / 2.0, env
|
112
|
+
.getMaxY()
|
113
|
+
+ offset);
|
114
|
+
this.frameVertex[1] = new jsts.triangulate.quadedge.Vertex(env.getMinX() - offset, env.getMinY() - offset);
|
115
|
+
this.frameVertex[2] = new jsts.triangulate.quadedge.Vertex(env.getMaxX() + offset, env.getMinY() - offset);
|
116
|
+
|
117
|
+
this.frameEnv = new jsts.geom.Envelope(this.frameVertex[0].getCoordinate(), this.frameVertex[1]
|
118
|
+
.getCoordinate());
|
119
|
+
this.frameEnv.expandToInclude(this.frameVertex[2].getCoordinate());
|
120
|
+
};
|
121
|
+
|
122
|
+
/**
|
123
|
+
* @return {jsts.geom.triangulate.quadedge.QuadEdge} The quadedge.
|
124
|
+
*/
|
125
|
+
jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.initSubdiv = function() {
|
126
|
+
var ea, eb, ec;
|
127
|
+
|
128
|
+
//build initial subdivision from frame
|
129
|
+
ea = this.makeEdge(this.frameVertex[0], this.frameVertex[1]);
|
130
|
+
eb = this.makeEdge(this.frameVertex[1], this.frameVertex[2]);
|
131
|
+
jsts.triangulate.quadedge.QuadEdge.splice(ea.sym(), eb);
|
132
|
+
ec = this.makeEdge(this.frameVertex[2], this.frameVertex[0]);
|
133
|
+
jsts.triangulate.quadedge.QuadEdge.splice(eb.sym(), ec);
|
134
|
+
jsts.triangulate.quadedge.QuadEdge.splice(ec.sym(), ea);
|
135
|
+
|
136
|
+
return ea;
|
137
|
+
};
|
138
|
+
|
139
|
+
/**
|
140
|
+
* Gets the vertex-equality tolerance value used in this subdivision
|
141
|
+
*
|
142
|
+
* @return {Number}
|
143
|
+
* the tolerance value.
|
144
|
+
*/
|
145
|
+
jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.getTolerance = function() {
|
146
|
+
return this.tolerance;
|
147
|
+
};
|
148
|
+
|
149
|
+
|
150
|
+
|
151
|
+
/**
|
152
|
+
* Gets the envelope of the Subdivision (including the frame).
|
153
|
+
*
|
154
|
+
* @return {jsts.geom.Envelope}
|
155
|
+
* the envelope.
|
156
|
+
*/
|
157
|
+
jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.getEnvelope = function() {
|
158
|
+
return new jsts.geom.Envelope(this.frameEnv);
|
159
|
+
};
|
160
|
+
|
161
|
+
/**
|
162
|
+
* Gets the collection of base {@link Quadedge}s (one for every pair of
|
163
|
+
* vertices which is connected).
|
164
|
+
*
|
165
|
+
* @return {jsts.triangulate.quadedge.QuadEdge[]}
|
166
|
+
* a collection of QuadEdges.
|
167
|
+
*/
|
168
|
+
jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.getEdges = function() {
|
169
|
+
if (arguments.length > 0) {
|
170
|
+
return this.getEdgesByFactory(arguments[0]);
|
171
|
+
}else {
|
172
|
+
return this.quadEdges;
|
173
|
+
}
|
174
|
+
};
|
175
|
+
|
176
|
+
/**
|
177
|
+
* Sets the {@link QuadEdgeLocator} to use for locating containing triangles
|
178
|
+
* in this subdivision.
|
179
|
+
*
|
180
|
+
* @param {jsts.triangulate.quadedge.QuadEdgeLocator}
|
181
|
+
* locator a QuadEdgeLocator.
|
182
|
+
*/
|
183
|
+
jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.setLocator = function(locator) {
|
184
|
+
this.locator = locator;
|
185
|
+
};
|
186
|
+
|
187
|
+
/**
|
188
|
+
* Creates a new quadedge, recording it in the edges list.
|
189
|
+
*
|
190
|
+
* @param {jsts.triangulate.quadedge.Vertex}
|
191
|
+
* o a Vertex.
|
192
|
+
* @param {jsts.triangulate.quadedge.Vertex}
|
193
|
+
* d another Vertex.
|
194
|
+
*
|
195
|
+
* @return {jsts.triangulate.quadedge.QuadEdge}
|
196
|
+
*/
|
197
|
+
jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.makeEdge = function(o, d) {
|
198
|
+
var q = jsts.triangulate.quadedge.QuadEdge.makeEdge(o, d);
|
199
|
+
this.quadEdges.push(q);
|
200
|
+
|
201
|
+
return q;
|
202
|
+
};
|
203
|
+
|
204
|
+
/**
|
205
|
+
* Creates a new QuadEdge connecting the destination of a to the origin of b,
|
206
|
+
* in such a way that all three have the same left face after the connection
|
207
|
+
* is complete. The quadedge is recorded in the edges list.
|
208
|
+
*
|
209
|
+
* @param {jsts.triangulate.quadedge.QuadEdge}
|
210
|
+
* a The first quadedge.
|
211
|
+
* @param {jsts.triangulate.quadedge.QuadEdge}
|
212
|
+
* b The second quadedge.
|
213
|
+
*
|
214
|
+
* @return {jsts.triangulate.quadedge.QuadEdge}
|
215
|
+
*/
|
216
|
+
jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.connect = function(a, b) {
|
217
|
+
var q = jsts.triangulate.quadedge.QuadEdge.connect(a, b);
|
218
|
+
this.quadEdges.push(q);
|
219
|
+
return q;
|
220
|
+
};
|
221
|
+
|
222
|
+
/**
|
223
|
+
* Deletes a quadedge from the subdivision. Linked quadedges are updated to
|
224
|
+
* reflect the deletion.
|
225
|
+
*
|
226
|
+
* @param {jsts.triangulate.quadedge.QuadEdge}
|
227
|
+
* e the quadedge to delete.
|
228
|
+
*/
|
229
|
+
jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.delete_jsts = function(e) {
|
230
|
+
jsts.triangulate.quadedge.QuadEdge.splice(e, e.oPrev());
|
231
|
+
jsts.triangulate.quadedge.QuadEdge.splice(e.sym(), e.sym().oPrev());
|
232
|
+
|
233
|
+
var eSym, eRot, eRotSym;
|
234
|
+
|
235
|
+
e.
|
236
|
+
eSym = e.sym();
|
237
|
+
eRot = e.rot;
|
238
|
+
eRotSym = e.rot.sym();
|
239
|
+
|
240
|
+
var idx = this.quadEdges.indexOf(e);
|
241
|
+
if (idx !== -1) {
|
242
|
+
this.quadEdges.splice(idx, 1);
|
243
|
+
}
|
244
|
+
|
245
|
+
idx = this.quadEdges.indexOf(eSym);
|
246
|
+
if (idx !== -1) {
|
247
|
+
this.quadEdges.splice(idx, 1);
|
248
|
+
}
|
249
|
+
|
250
|
+
idx = this.quadEdges.indexOf(eRot);
|
251
|
+
if (idx !== -1) {
|
252
|
+
this.quadEdges.splice(idx, 1);
|
253
|
+
}
|
254
|
+
|
255
|
+
idx = this.quadEdges.indexOf(eRotSym);
|
256
|
+
if (idx !== -1) {
|
257
|
+
this.quadEdges.splice(idx, 1);
|
258
|
+
}
|
259
|
+
|
260
|
+
e.delete_jsts();
|
261
|
+
eSym.delete_jsts();
|
262
|
+
eRot.delete_jsts();
|
263
|
+
eRotSym.delete_jsts();
|
264
|
+
};
|
265
|
+
|
266
|
+
/**
|
267
|
+
* Locates an edge of a triangle which contains a location specified by a
|
268
|
+
* Vertex v. The edge returned has the property that either v is on e, or e is
|
269
|
+
* an edge of a triangle containing v. The search starts from startEdge amd
|
270
|
+
* proceeds on the general direction of v.
|
271
|
+
* <p>
|
272
|
+
* This locate algorithm relies on the subdivision being Delaunay. For
|
273
|
+
* non-Delaunay subdivisions, this may loop for ever.
|
274
|
+
*
|
275
|
+
* @param {jsts.triangulate.quadedge.Vertex}
|
276
|
+
* v the location to search for.
|
277
|
+
* @param {jsts.triangulate.quadedge.QuadEdge}
|
278
|
+
* startEdge an edge of the subdivision to start searching at.
|
279
|
+
* @return {jsts.triangulate.quadedge.QuadEdge}
|
280
|
+
* a QuadEdge which contains v, or is on the edge of a triangle
|
281
|
+
* containing v.
|
282
|
+
*
|
283
|
+
* @throws jsts.error.LocateFailureError
|
284
|
+
* if the location algorithm fails to converge in a reasonable
|
285
|
+
* number of iterations
|
286
|
+
*/
|
287
|
+
jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.locateFromEdge = function(v, startEdge) {
|
288
|
+
var iter = 0, maxIter = this.quadEdges.length, e;
|
289
|
+
|
290
|
+
e = startEdge;
|
291
|
+
|
292
|
+
while (true) {
|
293
|
+
iter++;
|
294
|
+
/**
|
295
|
+
* So far it has always been the case that failure to locate indicates an
|
296
|
+
* invalid subdivision. So just fail completely. (An alternative would be
|
297
|
+
* to perform an exhaustive search for the containing triangle, but this
|
298
|
+
* would mask errors in the subdivision topology)
|
299
|
+
*
|
300
|
+
* This can also happen if two vertices are located very close together,
|
301
|
+
* since the orientation predicates may experience precision failures.
|
302
|
+
*/
|
303
|
+
if (iter > maxIter) {
|
304
|
+
throw new jsts.error.LocateFailureError(e.toLineSegment());
|
305
|
+
}
|
306
|
+
|
307
|
+
if ((v.equals(e.orig())) || (v.equals(e.dest()))) {
|
308
|
+
break;
|
309
|
+
} else if (v.rightOf(e)) {
|
310
|
+
e = e.sym();
|
311
|
+
} else if (!v.rightOf(e.oNext())) {
|
312
|
+
e = e.oNext();
|
313
|
+
} else if (!v.rightOf(e.dPrev())) {
|
314
|
+
e = e.dPrev();
|
315
|
+
} else {
|
316
|
+
// on edge or in triangle containing edge
|
317
|
+
break;
|
318
|
+
}
|
319
|
+
}
|
320
|
+
|
321
|
+
return e;
|
322
|
+
};
|
323
|
+
|
324
|
+
/**
|
325
|
+
* Locates a quadedge
|
326
|
+
* Will call correct locate* -function based on arguments
|
327
|
+
*/
|
328
|
+
jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.locate = function() {
|
329
|
+
if (arguments.length === 1) {
|
330
|
+
if (arguments[0] instanceof jsts.triangulate.quadedge.Vertex) {
|
331
|
+
return this.locateByVertex(arguments[0]);
|
332
|
+
}else {
|
333
|
+
return this.locateByCoordinate(arguments[0]);
|
334
|
+
}
|
335
|
+
}else {
|
336
|
+
return this.locateByCoordinates(arguments[0], arguments[1]);
|
337
|
+
}
|
338
|
+
};
|
339
|
+
|
340
|
+
/**
|
341
|
+
* Finds a quadedge of a triangle containing a location specified by a
|
342
|
+
* {@link Vertex}, if one exists.
|
343
|
+
*
|
344
|
+
* @param {jsts.triangulate.quadedge.Vertex}
|
345
|
+
* x the vertex to locate.
|
346
|
+
* @return {jsts.triangulate.quadedge.QuadEdge}
|
347
|
+
* a quadedge on the edge of a triangle which touches or contains the location, null of no such triangle exists.
|
348
|
+
*/
|
349
|
+
|
350
|
+
jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.locateByVertex = function(v) {
|
351
|
+
return this.locator.locate(v);
|
352
|
+
};
|
353
|
+
|
354
|
+
/**
|
355
|
+
* Finds a quadedge of a triangle containing a location specified by a
|
356
|
+
* {@link Coordinate}, if one exists.
|
357
|
+
*
|
358
|
+
* @param {jsts.geom.Coordinate}
|
359
|
+
* p the Coordinate to locate.
|
360
|
+
* @return {jsts.triangulate.quadedge.QuadEdge}
|
361
|
+
* a quadedge on the edge of a triangle which touches or contains the
|
362
|
+
* location or null if no such triangle exists.
|
363
|
+
*/
|
364
|
+
jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.locateByCoordinate = function(p) {
|
365
|
+
return this.locator.locate(new jsts.triangulate.quadedge.Vertex(p));
|
366
|
+
};
|
367
|
+
|
368
|
+
/**
|
369
|
+
* Locates the edge between the given vertices, if it exists in the
|
370
|
+
* subdivision.
|
371
|
+
*
|
372
|
+
* @param {jsts.geom.Coordinate}
|
373
|
+
* p0 a coordinate.
|
374
|
+
* @param {jsts.geom.Coordinate}
|
375
|
+
* p1 another coordinate.
|
376
|
+
* @return {jsts.triangulate.quadedge.QuadEdge}
|
377
|
+
* the edge joining the coordinates, if present, null if no such edge exists.
|
378
|
+
*/
|
379
|
+
jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.locateByCoordinates = function(p0, p1) {
|
380
|
+
var e, base, locEdge;
|
381
|
+
// find an edge containing one of the points
|
382
|
+
var e = this.locator.locate(new jsts.triangulate.quadedge.Vertex(p0));
|
383
|
+
if (e === null) {
|
384
|
+
return null;
|
385
|
+
}
|
386
|
+
|
387
|
+
// normalize so that p0 is origin of base edge
|
388
|
+
base = e;
|
389
|
+
if (e.dest().getCoordinate().equals2D(p0)) {
|
390
|
+
base = e.sym();
|
391
|
+
}
|
392
|
+
|
393
|
+
// check all edges around origin of base edge
|
394
|
+
locEdge = base;
|
395
|
+
do {
|
396
|
+
if (locEdge.dest().getCoordinate().equals2D(p1)) {
|
397
|
+
return locEdge;
|
398
|
+
}
|
399
|
+
locEdge = locEdge.oNext();
|
400
|
+
} while (locEdge != base);
|
401
|
+
return null;
|
402
|
+
};
|
403
|
+
|
404
|
+
/**
|
405
|
+
* Inserts a new site into the Subdivision, connecting it to the vertices of
|
406
|
+
* the containing triangle (or quadrilateral, if the split point falls on an
|
407
|
+
* existing edge).
|
408
|
+
* <p>
|
409
|
+
* This method does NOT maintain the Delaunay condition. If desired, this must
|
410
|
+
* be checked and enforced by the caller.
|
411
|
+
* <p>
|
412
|
+
* This method does NOT check if the inserted vertex falls on an edge. This
|
413
|
+
* must be checked by the caller, since this situation may cause erroneous
|
414
|
+
* triangulation
|
415
|
+
*
|
416
|
+
* @param {jsts.triangulate.quadedge.Vertex}
|
417
|
+
* v the vertex to insert.
|
418
|
+
* @return {jsts.triangulate.quadedge.QuadEdge}
|
419
|
+
* a new quad edge terminating in v.
|
420
|
+
*/
|
421
|
+
jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.insertSite = function(v) {
|
422
|
+
var e, base, startEdge;
|
423
|
+
|
424
|
+
e = this.locate(v);
|
425
|
+
|
426
|
+
if ((v.equals(e.orig(), this.tolerance)) || (v.equals(e.dest(), this.tolerance))) {
|
427
|
+
return e; // point already in subdivision.
|
428
|
+
}
|
429
|
+
|
430
|
+
// Connect the new point to the vertices of the containing
|
431
|
+
// triangle (or quadrilateral, if the new point fell on an
|
432
|
+
// existing edge.)
|
433
|
+
base = this.makeEdge(e.orig(), v);
|
434
|
+
jsts.triangulate.quadedge.QuadEdge.splice(base, e);
|
435
|
+
startEdge = base;
|
436
|
+
do {
|
437
|
+
base = this.connect(e, base.sym());
|
438
|
+
e = base.oPrev();
|
439
|
+
} while (e.lNext() != startEdge);
|
440
|
+
|
441
|
+
return startEdge;
|
442
|
+
};
|
443
|
+
|
444
|
+
/**
|
445
|
+
* Tests whether a QuadEdge is an edge incident on a frame triangle vertex.
|
446
|
+
*
|
447
|
+
* @param {jsts.triangulate.quadedge.QuadEdge}
|
448
|
+
* e the edge to test.
|
449
|
+
* @return {boolean}
|
450
|
+
* true if the edge is connected to the frame triangle.
|
451
|
+
*/
|
452
|
+
jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.isFrameEdge = function(e) {
|
453
|
+
if (this.isFrameVertex(e.orig()) || this.isFrameVertex(e.dest())) {
|
454
|
+
return true;
|
455
|
+
}
|
456
|
+
return false;
|
457
|
+
};
|
458
|
+
|
459
|
+
/**
|
460
|
+
* Tests whether a QuadEdge is an edge on the border of the frame facets and
|
461
|
+
* the internal facets. E.g. an edge which does not itself touch a frame
|
462
|
+
* vertex, but which touches an edge which does.
|
463
|
+
*
|
464
|
+
* @param {jsts.triangulate.quadedge.QuadEdge}
|
465
|
+
* e the edge to test.
|
466
|
+
* @return {boolean}
|
467
|
+
* true if the edge is on the border of the frame.
|
468
|
+
*/
|
469
|
+
jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.isFrameBorderEdge = function(e) {
|
470
|
+
// MD debugging
|
471
|
+
var leftTri, rightTri, vLeftTriOther, vRightTriOther;
|
472
|
+
|
473
|
+
leftTri = new Array(3);
|
474
|
+
this.getTriangleEdges(e, leftTri);
|
475
|
+
|
476
|
+
rightTri = new Array(3);
|
477
|
+
this.getTriangleEdges(e.sym(), rightTri);
|
478
|
+
|
479
|
+
// check other vertex of triangle to left of edge
|
480
|
+
vLeftTriOther = e.lNext().dest();
|
481
|
+
|
482
|
+
if (this.isFrameVertex(vLeftTriOther)) {
|
483
|
+
return true;
|
484
|
+
}
|
485
|
+
|
486
|
+
// check other vertex of triangle to right of edge
|
487
|
+
vRightTriOther = e.sym().lNext().dest();
|
488
|
+
if (this.isFrameVertex(vRightTriOther)) {
|
489
|
+
return true;
|
490
|
+
}
|
491
|
+
|
492
|
+
return false;
|
493
|
+
};
|
494
|
+
|
495
|
+
/**
|
496
|
+
* Tests whether a vertex is a vertex of the outer triangle.
|
497
|
+
*
|
498
|
+
* @param {jsts.triangulate.quadedge.Vertex}
|
499
|
+
* v the vertex to test.
|
500
|
+
* @return {boolean}
|
501
|
+
* true if the vertex is an outer triangle vertex.
|
502
|
+
*/
|
503
|
+
jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.isFrameVertex = function(v) {
|
504
|
+
if (v.equals(this.frameVertex[0])) {
|
505
|
+
return true;
|
506
|
+
}
|
507
|
+
if (v.equals(this.frameVertex[1])) {
|
508
|
+
return true;
|
509
|
+
}
|
510
|
+
if (v.equals(this.frameVertex[2])) {
|
511
|
+
return true;
|
512
|
+
}
|
513
|
+
return false;
|
514
|
+
};
|
515
|
+
|
516
|
+
/**
|
517
|
+
* Tests whether a {@link Coordinate} lies on a {@link QuadEdge}, up to a
|
518
|
+
* tolerance determined by the subdivision tolerance.
|
519
|
+
*
|
520
|
+
* @param {jsts.triangulate.quadedge.QuadEdge}
|
521
|
+
* e a QuadEdge.
|
522
|
+
* @param {jsts.geom.Coordinate}
|
523
|
+
* p a point.
|
524
|
+
* @return {boolean}
|
525
|
+
* true if the vertex lies on the edge.
|
526
|
+
*/
|
527
|
+
jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.isOnEdge = function(e, p) {
|
528
|
+
this.seg.setCoordinates(e.orig().getCoordinate(), e.dest().getCoordinate());
|
529
|
+
var dist = this.seg.distance(p);
|
530
|
+
|
531
|
+
// heuristic (hack?)
|
532
|
+
return dist < this.edgeCoincidenceTolerance;
|
533
|
+
};
|
534
|
+
|
535
|
+
/**
|
536
|
+
* Tests whether a {@link Vertex} is the start or end vertex of a
|
537
|
+
* {@link QuadEdge}, up to the subdivision tolerance distance.
|
538
|
+
*
|
539
|
+
* @param {jsts.triangulate.quadedge.QuadEdge}
|
540
|
+
* e the quadedge to test.
|
541
|
+
* @param {jsts.triangulate.quadedge.Vertex}
|
542
|
+
* v the vertex to test.
|
543
|
+
*
|
544
|
+
* @return {boolean}
|
545
|
+
* true if the vertex is a endpoint of the edge.
|
546
|
+
*/
|
547
|
+
jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.isVertexOfEdge = function(e, v) {
|
548
|
+
if ((v.equals(e.orig(), this.tolerance)) || (v.equals(e.dest(), this.tolerance))) {
|
549
|
+
return true;
|
550
|
+
}
|
551
|
+
return false;
|
552
|
+
};
|
553
|
+
|
554
|
+
/**
|
555
|
+
* Gets the unique {@link Vertex}es in the subdivision, including the frame
|
556
|
+
* vertices if desired.
|
557
|
+
*
|
558
|
+
* @param {boolean}
|
559
|
+
* includeFrame true if the frame vertices should be included.
|
560
|
+
* @return {jsts.triangulate.quadedge.Vertex[]} an array of the subdivision vertices.
|
561
|
+
*
|
562
|
+
* @see #getVertexUniqueEdges
|
563
|
+
*/
|
564
|
+
jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.getVertices = function(includeFrame)
|
565
|
+
{
|
566
|
+
var vertices = [], i, il, qe, v, vd;
|
567
|
+
|
568
|
+
i = 0, il = this.quadEdges.length;
|
569
|
+
|
570
|
+
for (i; i < il; i++) {
|
571
|
+
qe = this.quadEdges[i];
|
572
|
+
v = qe.orig();
|
573
|
+
|
574
|
+
if (includeFrame || !this.isFrameVertex(v)) {
|
575
|
+
vertices.push(v);
|
576
|
+
}
|
577
|
+
|
578
|
+
/**
|
579
|
+
* Inspect the sym edge as well, since it is possible that a vertex is
|
580
|
+
* only at the dest of all tracked quadedges.
|
581
|
+
*/
|
582
|
+
|
583
|
+
vd = qe.dest();
|
584
|
+
if (includeFrame || !this.isFrameVertex(vd)) {
|
585
|
+
vertices.push(vd);
|
586
|
+
}
|
587
|
+
}
|
588
|
+
|
589
|
+
return vertices;
|
590
|
+
};
|
591
|
+
|
592
|
+
/**
|
593
|
+
* Gets a collection of {@link QuadEdge}s whose origin vertices are a unique
|
594
|
+
* set which includes all vertices in the subdivision. The frame vertices can
|
595
|
+
* be included if required.
|
596
|
+
* <p>
|
597
|
+
* This is useful for algorithms which require traversing the subdivision
|
598
|
+
* starting at all vertices. Returning a quadedge for each vertex is more
|
599
|
+
* efficient than the alternative of finding the actual vertices using
|
600
|
+
* {@link #getVertices) and then locating quadedges attached to them.
|
601
|
+
*
|
602
|
+
* @param {boolean}
|
603
|
+
* includeFrame true if the frame vertices should be included.
|
604
|
+
* @return {jsts.triangulate.quadedge.QuadEdge[]}
|
605
|
+
* a collection of QuadEdge with the vertices of the subdivision as
|
606
|
+
* their origins.
|
607
|
+
*/
|
608
|
+
jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.getVertexUniqueEdges = function(includeFrame)
|
609
|
+
{
|
610
|
+
var edges, visitedVertices, i, il, qe, v, qd, vd;
|
611
|
+
|
612
|
+
edges = [];
|
613
|
+
visitedVertices = [];
|
614
|
+
|
615
|
+
i = 0, il = this.quadEdges.length;
|
616
|
+
for (i; i < il; i++) {
|
617
|
+
qe = this.quadEdges[i];
|
618
|
+
v = qe.orig();
|
619
|
+
|
620
|
+
if (visitedVertices.indexOf(v) === -1) {
|
621
|
+
visitedVertices.push(v);
|
622
|
+
if (includeFrame || ! this.isFrameVertex(v)) {
|
623
|
+
edges.push(qe);
|
624
|
+
}
|
625
|
+
}
|
626
|
+
|
627
|
+
/**
|
628
|
+
* Inspect the sym edge as well, since it is possible that a vertex is
|
629
|
+
* only at the dest of all tracked quadedges.
|
630
|
+
*/
|
631
|
+
qd = qe.sym();
|
632
|
+
vd = qd.orig();
|
633
|
+
|
634
|
+
if (visitedVertices.indexOf(vd) === -1) {
|
635
|
+
visitedVertices.push(vd);
|
636
|
+
if (includeFrame || ! this.isFrameVertex(vd)) {
|
637
|
+
edges.push(qd);
|
638
|
+
}
|
639
|
+
}
|
640
|
+
}
|
641
|
+
|
642
|
+
return edges;
|
643
|
+
};
|
644
|
+
|
645
|
+
/**
|
646
|
+
* Gets all primary quadedges in the subdivision. A primary edge is a
|
647
|
+
* {@link QuadEdge} which occupies the 0'th position in its array of
|
648
|
+
* associated quadedges. These provide the unique geometric edges of the
|
649
|
+
* triangulation.
|
650
|
+
*
|
651
|
+
* @param {boolean}
|
652
|
+
* includeFrame true if the frame edges are to be included.
|
653
|
+
*
|
654
|
+
* @return {jsts.triangulate.quadedge.QuadEdge[]}
|
655
|
+
* a List of QuadEdges.
|
656
|
+
*/
|
657
|
+
jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.getPrimaryEdges = function(includeFrame) {
|
658
|
+
this.visitedKey++;
|
659
|
+
|
660
|
+
var edges, edgeStack, visitedEdges, edge, priQE;
|
661
|
+
|
662
|
+
edges = [];
|
663
|
+
edgeStack = [];
|
664
|
+
edgeStack.push(this.startingEdge);
|
665
|
+
|
666
|
+
visitedEdges = [];
|
667
|
+
|
668
|
+
while (edgeStack.length > 0) {
|
669
|
+
edge = edgeStack.pop();
|
670
|
+
if (visitedEdges.indexOf(edge) === -1) {
|
671
|
+
priQE = edge.getPrimary();
|
672
|
+
|
673
|
+
if (includeFrame || !this.isFrameEdge(priQE)) {
|
674
|
+
edges.push(priQE);
|
675
|
+
}
|
676
|
+
|
677
|
+
edgeStack.push(edge.oNext());
|
678
|
+
edgeStack.push(edge.sym().oNext());
|
679
|
+
|
680
|
+
visitedEdges.push(edge);
|
681
|
+
visitedEdges.push(edge.sym());
|
682
|
+
}
|
683
|
+
}
|
684
|
+
return edges;
|
685
|
+
};
|
686
|
+
|
687
|
+
|
688
|
+
|
689
|
+
/*****************************************************************************
|
690
|
+
* Visitors
|
691
|
+
****************************************************************************/
|
692
|
+
|
693
|
+
/**
|
694
|
+
* Visits all quadedges with the specified visitor.
|
695
|
+
*
|
696
|
+
* @param {jsts.triangulate.TriangleVisitor}
|
697
|
+
* triVisitor the visitor to use.
|
698
|
+
*
|
699
|
+
* @param {boolean}
|
700
|
+
* includeFrame true to include frame-edges.
|
701
|
+
*/
|
702
|
+
jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.visitTriangles = function(triVisitor, includeFrame) {
|
703
|
+
this.visitedKey++;
|
704
|
+
|
705
|
+
// visited flag is used to record visited edges of triangles
|
706
|
+
// setVisitedAll(false);
|
707
|
+
var edgeStack, visitedEdges, edge, triEdges;
|
708
|
+
|
709
|
+
edgeStack = [];
|
710
|
+
edgeStack.push(this.startingEdge);
|
711
|
+
|
712
|
+
visitedEdges = [];
|
713
|
+
|
714
|
+
while (edgeStack.length > 0) {
|
715
|
+
edge = edgeStack.pop();
|
716
|
+
if (visitedEdges.indexOf(edge) === -1) {
|
717
|
+
triEdges = this.fetchTriangleToVisit(edge, edgeStack, includeFrame, visitedEdges);
|
718
|
+
if (triEdges !== null)
|
719
|
+
triVisitor.visit(triEdges);
|
720
|
+
}
|
721
|
+
}
|
722
|
+
};
|
723
|
+
|
724
|
+
/**
|
725
|
+
* Stores the edges for a visited triangle. Also pushes sym (neighbour) edges
|
726
|
+
* on stack to visit later.
|
727
|
+
*
|
728
|
+
* @param {jsts.triangulate.quadedge.QuadEdge}
|
729
|
+
* edge the quadedge.
|
730
|
+
* @param {jsts.triangulate.quadedge.QuadEdge[]}
|
731
|
+
* edgeStack an array used as a stack.
|
732
|
+
* @param {boolean}
|
733
|
+
* includeFrame true to include frame.
|
734
|
+
* @param {jsts.traingulate.quadedge.QuadEdge[]}
|
735
|
+
* visitedEdges the edges that are already visited.
|
736
|
+
* @return {jsts.triangulate.quadedge.QuadEdge[]}
|
737
|
+
* the visited triangle edges or null if the triangle should not be visited.
|
738
|
+
*/
|
739
|
+
jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.fetchTriangleToVisit = function(edge, edgeStack, includeFrame, visitedEdges) {
|
740
|
+
var curr, edgeCount, isFrame, sym;
|
741
|
+
|
742
|
+
curr = edge;
|
743
|
+
edgeCount = 0;
|
744
|
+
isFrame = false;
|
745
|
+
|
746
|
+
do {
|
747
|
+
this.triEdges[edgeCount] = curr;
|
748
|
+
|
749
|
+
if (this.isFrameEdge(curr)) {
|
750
|
+
isFrame = true;
|
751
|
+
}
|
752
|
+
// push sym edges to visit next
|
753
|
+
sym = curr.sym();
|
754
|
+
if (visitedEdges.indexOf(sym) === -1) {
|
755
|
+
edgeStack.push(sym);
|
756
|
+
}
|
757
|
+
// mark this edge as visited
|
758
|
+
visitedEdges.push(curr);
|
759
|
+
|
760
|
+
edgeCount++;
|
761
|
+
curr = curr.lNext();
|
762
|
+
} while (curr !== edge);
|
763
|
+
|
764
|
+
if (isFrame && !includeFrame) {
|
765
|
+
return null;
|
766
|
+
}
|
767
|
+
return this.triEdges;
|
768
|
+
};
|
769
|
+
|
770
|
+
/**
|
771
|
+
* Gets a list of the triangles in the subdivision, specified as an array of
|
772
|
+
* the primary quadedges around the triangle.
|
773
|
+
*
|
774
|
+
* @param includeFrame
|
775
|
+
* true if the frame triangles should be included.
|
776
|
+
* @return {jsts.triangulate.quadedge.QuadEdge[]}
|
777
|
+
* a List of QuadEdge[3] arrays.
|
778
|
+
*/
|
779
|
+
jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.getTriangleEdges = function(includeFrame) {
|
780
|
+
var visitor = new jsts.triangulate.quadedge.TriangleEdgesListVisitor();
|
781
|
+
this.visitTriangles(visitor, includeFrame);
|
782
|
+
return visitor.getTriangleEdges();
|
783
|
+
};
|
784
|
+
|
785
|
+
/**
|
786
|
+
* Gets a list of the triangles in the subdivision, specified as an array of
|
787
|
+
* the triangle {@link Vertex}es.
|
788
|
+
*
|
789
|
+
* @param {boolean}
|
790
|
+
* includeFrame true if the frame triangles should be included.
|
791
|
+
* @return {jsts.triangulate.quadedge.Vertex[][]} a List of Vertex[3] arrays.
|
792
|
+
*/
|
793
|
+
jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.getTriangleVertices = function(includeFrame) {
|
794
|
+
var visitor = new TriangleVertexListVisitor();
|
795
|
+
this.visitTriangles(visitor, includeFrame);
|
796
|
+
|
797
|
+
return visitor.getTriangleVertices();
|
798
|
+
};
|
799
|
+
|
800
|
+
/**
|
801
|
+
* Gets the coordinates for each triangle in the subdivision as an array.
|
802
|
+
*
|
803
|
+
* @param {boolean}
|
804
|
+
* includeFrame true if the frame triangles should be included.
|
805
|
+
* @return {jsts.geom.Coordinate[][]}
|
806
|
+
* a list of Coordinate[4] representing each triangle.
|
807
|
+
*/
|
808
|
+
jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.getTriangleCoordinates = function(includeFrame) {
|
809
|
+
var visitor = new jsts.triangulate.quadedge.TriangleCoordinatesVisitor();
|
810
|
+
this.visitTriangles(visitor, includeFrame);
|
811
|
+
return visitor.getTriangles();
|
812
|
+
};
|
813
|
+
|
814
|
+
|
815
|
+
|
816
|
+
/**
|
817
|
+
* Gets the geometry for the edges in the subdivision as a
|
818
|
+
* {@link MultiLineString} containing 2-point lines.
|
819
|
+
*
|
820
|
+
* @param {jsts.geom.GeometryFactory}
|
821
|
+
* geomFact the GeometryFactory to use.
|
822
|
+
* @return {jsts.geom.Geometry}
|
823
|
+
* a MultiLineString.
|
824
|
+
*/
|
825
|
+
jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.getEdgesByFactory = function(geomFact) {
|
826
|
+
var quadEdges, edges, i, il, qe, coords;
|
827
|
+
|
828
|
+
quadEdges = this.getPrimaryEdges(false);
|
829
|
+
edges = [];
|
830
|
+
|
831
|
+
i = 0;
|
832
|
+
il = quadEdges.length;
|
833
|
+
|
834
|
+
for (i; i < il; i++) {
|
835
|
+
qe = quadEdges[i];
|
836
|
+
coords = [];
|
837
|
+
coords[0] = (qe.orig().getCoordinate());
|
838
|
+
coords[1] = (qe.dest().getCoordinate());
|
839
|
+
edges[i] = geomFact.createLineString(coords);
|
840
|
+
}
|
841
|
+
|
842
|
+
return geomFact.createMultiLineString(edges);
|
843
|
+
};
|
844
|
+
|
845
|
+
/**
|
846
|
+
* Gets the geometry for the triangles in a triangulated subdivision as a
|
847
|
+
* {@link GeometryCollection} of triangular {@link Polygon}s.
|
848
|
+
*
|
849
|
+
* @param {jsts.geom.GeometryFactory}
|
850
|
+
* geomFact the GeometryFactory to use.
|
851
|
+
* @return {jsts.geom.Geometry}
|
852
|
+
* a GeometryCollection of triangular Polygons.
|
853
|
+
*/
|
854
|
+
jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.getTriangles = function(geomFact) {
|
855
|
+
var triPtsList, tris, triPt, i, il;
|
856
|
+
triPtsList = this.getTriangleCoordinates(false);
|
857
|
+
tris = new Array(triPtsList.length);
|
858
|
+
|
859
|
+
i = 0, il = triPtsList.length;
|
860
|
+
for (i; i < il; i++) {
|
861
|
+
triPt = triPtsList[i];
|
862
|
+
tris[i] = geomFact.createPolygon(geomFact.createLinearRing(triPt, null));
|
863
|
+
}
|
864
|
+
|
865
|
+
return geomFact.createGeometryCollection(tris);
|
866
|
+
};
|
867
|
+
|
868
|
+
/**
|
869
|
+
* Gets the cells in the Voronoi diagram for this triangulation. The cells are
|
870
|
+
* returned as a {@link GeometryCollection} of {@link Polygon}s
|
871
|
+
* <p>
|
872
|
+
* The userData of each polygon is set to be the {@link Coordinate) of the
|
873
|
+
* cell site. This allows easily associating external data associated with the
|
874
|
+
* sites to the cells.
|
875
|
+
*
|
876
|
+
* @param {jsts.geom.GeometryFactory}
|
877
|
+
* geomFact a geometry factory.
|
878
|
+
* @return {jsts.geom.Geometry}
|
879
|
+
* a GeometryCollection of Polygons.
|
880
|
+
*/
|
881
|
+
jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.getVoronoiDiagram = function(geomFact)
|
882
|
+
{
|
883
|
+
var vorCells = this.getVoronoiCellPolygons(geomFact);
|
884
|
+
return geomFact.createGeometryCollection(vorCells);
|
885
|
+
};
|
886
|
+
|
887
|
+
/**
|
888
|
+
* Gets a List of {@link Polygon}s for the Voronoi cells of this
|
889
|
+
* triangulation.
|
890
|
+
* <p>
|
891
|
+
* The userData of each polygon is set to be the {@link Coordinate) of the
|
892
|
+
* cell site. This allows easily associating external data associated with the
|
893
|
+
* sites to the cells.
|
894
|
+
*
|
895
|
+
* @param {jsts.geom.GeometryFactory}
|
896
|
+
* geomFact a geometry factory.
|
897
|
+
* @return {jsts.geom.Polygon[]}
|
898
|
+
* an array of Polygons.
|
899
|
+
*/
|
900
|
+
jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.getVoronoiCellPolygons = function(geomFact)
|
901
|
+
{
|
902
|
+
/*
|
903
|
+
* Compute circumcentres of triangles as vertices for dual edges.
|
904
|
+
* Precomputing the circumcentres is more efficient,
|
905
|
+
* and more importantly ensures that the computed centres
|
906
|
+
* are consistent across the Voronoi cells.
|
907
|
+
*/
|
908
|
+
this.visitTriangles(new jsts.triangulate.quadedge.TriangleCircumcentreVisitor(), true);
|
909
|
+
|
910
|
+
var cells, edges, i, il, qe;
|
911
|
+
cells = [];
|
912
|
+
edges = this.getVertexUniqueEdges(false);
|
913
|
+
|
914
|
+
i = 0, il = edges.length;
|
915
|
+
for (i; i < il; i++) {
|
916
|
+
qe = edges[i];
|
917
|
+
cells.push(this.getVoronoiCellPolygon(qe, geomFact));
|
918
|
+
}
|
919
|
+
|
920
|
+
return cells;
|
921
|
+
};
|
922
|
+
|
923
|
+
/**
|
924
|
+
* Gets the Voronoi cell around a site specified by the origin of a QuadEdge.
|
925
|
+
* <p>
|
926
|
+
* The userData of the polygon is set to be the {@link Coordinate) of the
|
927
|
+
* site. This allows attaching external data associated with the site to this
|
928
|
+
* cell polygon.
|
929
|
+
*
|
930
|
+
* @param {jsts.triangulate.quadedge.QuadEdge}
|
931
|
+
* qe a quadedge originating at the cell site.
|
932
|
+
* @param {jsts.geom.GeometryFactory}
|
933
|
+
* geomFact a factory for building the polygon.
|
934
|
+
* @return {jsts.geom.Polygon}
|
935
|
+
* a polygon indicating the cell extent.
|
936
|
+
*/
|
937
|
+
jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.getVoronoiCellPolygon = function(qe, geomFact)
|
938
|
+
{
|
939
|
+
var cellPts, startQe, cc, coordList, cellPoly, v;
|
940
|
+
|
941
|
+
cellPts = [];
|
942
|
+
startQE = qe;
|
943
|
+
do {
|
944
|
+
// Coordinate cc = circumcentre(qe);
|
945
|
+
// use previously computed circumcentre
|
946
|
+
cc = qe.rot.orig().getCoordinate();
|
947
|
+
cellPts.push(cc);
|
948
|
+
|
949
|
+
// move to next triangle CW around vertex
|
950
|
+
qe = qe.oPrev();
|
951
|
+
} while (qe !== startQE);
|
952
|
+
|
953
|
+
coordList = new jsts.geom.CoordinateList([], false);
|
954
|
+
coordList.add(cellPts, false);
|
955
|
+
coordList.closeRing();
|
956
|
+
|
957
|
+
if (coordList.size() < 4) {
|
958
|
+
//System.out.println(coordList);
|
959
|
+
coordList.add(coordList.get(coordList.size() - 1), true);
|
960
|
+
}
|
961
|
+
|
962
|
+
cellPoly = geomFact.createPolygon(geomFact.createLinearRing(coordList.toArray()), null);
|
963
|
+
|
964
|
+
v = startQE.orig();
|
965
|
+
//cellPoly.setUserData(v.getCoordinate());
|
966
|
+
return cellPoly;
|
967
|
+
};
|
968
|
+
|
969
|
+
|
970
|
+
|
971
|
+
/**
|
972
|
+
* A TriangleVisitor which computes and sets the circumcentre as the origin of
|
973
|
+
* the dual edges originating in each triangle.
|
974
|
+
*
|
975
|
+
* @author mbdavis
|
976
|
+
*
|
977
|
+
*/
|
978
|
+
jsts.triangulate.quadedge.TriangleCircumcentreVisitor = function() {
|
979
|
+
};
|
980
|
+
|
981
|
+
/**
|
982
|
+
* Visits all the edges
|
983
|
+
*
|
984
|
+
* @param {jsts.triangulate.quadedge.QuadEdge[]}
|
985
|
+
* triEdges the edges to visit.
|
986
|
+
*/
|
987
|
+
jsts.triangulate.quadedge.TriangleCircumcentreVisitor.prototype.visit = function(triEdges) {
|
988
|
+
var a, b, c, cc, ccVertex, i;
|
989
|
+
|
990
|
+
a = triEdges[0].orig().getCoordinate();
|
991
|
+
b = triEdges[1].orig().getCoordinate();
|
992
|
+
c = triEdges[2].orig().getCoordinate();
|
993
|
+
|
994
|
+
//TODO: choose the most accurate circumcentre based on the edges
|
995
|
+
cc = jsts.geom.Triangle.circumcentre(a, b, c);
|
996
|
+
ccVertex = new jsts.triangulate.quadedge.Vertex(cc);
|
997
|
+
|
998
|
+
//save the circumcentre as the origin for the dual edges originating in
|
999
|
+
// this triangle
|
1000
|
+
i = 0;
|
1001
|
+
|
1002
|
+
for (i; i < 3; i++) {
|
1003
|
+
triEdges[i].rot.setOrig(ccVertex);
|
1004
|
+
}
|
1005
|
+
};
|
1006
|
+
|
1007
|
+
jsts.triangulate.quadedge.TriangleEdgesListVisitor = function() {
|
1008
|
+
this.triList = [];
|
1009
|
+
};
|
1010
|
+
|
1011
|
+
jsts.triangulate.quadedge.TriangleEdgesListVisitor.prototype.visit = function(triEdges) {
|
1012
|
+
var clone = triEdges.concat(); //concat without arguments returns a copy of the array
|
1013
|
+
this.triList.push(clone);
|
1014
|
+
};
|
1015
|
+
|
1016
|
+
jsts.triangulate.quadedge.TriangleEdgesListVisitor.prototype.getTriangleEdges = function() {
|
1017
|
+
return this.triList;
|
1018
|
+
};
|
1019
|
+
|
1020
|
+
jsts.triangulate.quadedge.TriangleVertexListVisitor = function() {
|
1021
|
+
this.triList = [];
|
1022
|
+
};
|
1023
|
+
|
1024
|
+
jsts.triangulate.quadedge.TriangleVertexListVisitor.prototype.visit = function(triEdges) {
|
1025
|
+
var vertices = [];
|
1026
|
+
vertices.push(trieEdges[0].orig());
|
1027
|
+
vertices.push(trieEdges[1].orig());
|
1028
|
+
vertices.push(trieEdges[2].orig());
|
1029
|
+
this.triList.push(vertices);
|
1030
|
+
};
|
1031
|
+
|
1032
|
+
jsts.triangulate.quadedge.TriangleVertexListVisitor.prototype.getTriangleVertices = function() {
|
1033
|
+
return this.triList;
|
1034
|
+
};
|
1035
|
+
|
1036
|
+
jsts.triangulate.quadedge.TriangleCoordinatesVisitor = function() {
|
1037
|
+
this.coordList = new jsts.geom.CoordinateList([], false);
|
1038
|
+
this.triCoords = [];
|
1039
|
+
};
|
1040
|
+
|
1041
|
+
jsts.triangulate.quadedge.TriangleCoordinatesVisitor.prototype.visit = function(triEdges) {
|
1042
|
+
this.coordList = new jsts.geom.CoordinateList([], false);
|
1043
|
+
|
1044
|
+
var i = 0, v, pts;
|
1045
|
+
|
1046
|
+
for (i; i < 3; i++) {
|
1047
|
+
v = triEdges[i].orig();
|
1048
|
+
this.coordList.add(v.getCoordinate());
|
1049
|
+
}
|
1050
|
+
|
1051
|
+
if (this.coordList.size() > 0) {
|
1052
|
+
this.coordList.closeRing();
|
1053
|
+
pts = this.coordList.toArray();
|
1054
|
+
if (pts.length !== 4) {
|
1055
|
+
return;
|
1056
|
+
}
|
1057
|
+
|
1058
|
+
this.triCoords.push(pts);
|
1059
|
+
}
|
1060
|
+
};
|
1061
|
+
|
1062
|
+
jsts.triangulate.quadedge.TriangleCoordinatesVisitor.prototype.getTriangles = function() {
|
1063
|
+
return this.triCoords;
|
1064
|
+
};
|