diff --git a/src/org/poly2tri/Poly2Tri.scala b/src/org/poly2tri/Poly2Tri.scala index 4bb0bf0..5431747 100644 --- a/src/org/poly2tri/Poly2Tri.scala +++ b/src/org/poly2tri/Poly2Tri.scala @@ -41,6 +41,10 @@ import org.newdawn.slick.geom.{Polygon, Circle} import scala.collection.mutable.ArrayBuffer import scala.io.Source +import seidel.Triangulator +import shapes.{Segment, Point, Triangle} +import earClip.EarClip + // TODO: Lots of documentation! object Poly2Tri { @@ -103,10 +107,10 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") { polygon.addPoint(v.x, v.y) } if(!drawMap) { - val lCirc = new Circle(t.leftPoint.x, t.leftPoint.y, 4) - g.setColor(blue); g.draw(lCirc); g.fill(lCirc) - val rCirc = new Circle(t.rightPoint.x+5, t.rightPoint.y, 4) - g.setColor(yellow); g.draw(rCirc); g.fill(rCirc) + //val lCirc = new Circle(t.leftPoint.x, t.leftPoint.y, 4) + //g.setColor(blue); g.draw(lCirc); g.fill(lCirc) + //val rCirc = new Circle(t.rightPoint.x+5, t.rightPoint.y, 4) + //g.setColor(yellow); g.draw(rCirc); g.fill(rCirc) } g.setColor(red) g.draw(polygon) diff --git a/src/org/poly2tri/EarClip.scala b/src/org/poly2tri/earClip/EarClip.scala similarity index 87% rename from src/org/poly2tri/EarClip.scala rename to src/org/poly2tri/earClip/EarClip.scala index efeeb65..55a7f6e 100644 --- a/src/org/poly2tri/EarClip.scala +++ b/src/org/poly2tri/earClip/EarClip.scala @@ -1,5 +1,3 @@ -package org.poly2tri - /** * Ported from jBox2D. Original author: ewjordan * Triangulates a polygon using simple ear-clipping algorithm. Returns @@ -25,6 +23,10 @@ package org.poly2tri * or fewer (due to pinch point polygon snipping), so allocate an array of * this size. */ +package org.poly2tri.earClip + +import shapes.{Point, Triangle} + class EarClip { val tol = .001f @@ -311,56 +313,3 @@ class Poly(var x: Array[Float], var y: Array[Float], var nVertices: Int) { areaIsSet = false } } - -class Triangle(var x1: Float, var y1: Float, var x2: Float, var y2: Float, var x3: Float, var y3: Float) { - - def this() = this(0,0,0,0,0,0) - - val x = new Array[Float](3) - val y = new Array[Float](3) - - // Automatically fixes orientation to ccw - - val dx1 = x2-x1 - val dx2 = x3-x1 - val dy1 = y2-y1 - val dy2 = y3-y1 - val cross = dx1*dy2-dx2*dy1 - val ccw = (cross>0) - if (ccw){ - x(0) = x1; x(1) = x2; x(2) = x3; - y(0) = y1; y(1) = y2; y(2) = y3; - } else{ - x(0) = x1; x(1) = x3; x(2) = x2; - y(0) = y1; y(1) = y3; y(2) = y2; - } - - def set(t: Triangle) { - x(0) = t.x(0) - x(1) = t.x(1) - x(2) = t.x(2) - y(0) = t.y(0) - y(1) = t.y(1) - y(2) = t.y(2) - } - - - def containsPoint(_x: Float, _y: Float): Boolean = { - - val vx2 = _x-x(0); val vy2 = _y-y(0); - val vx1 = x(1)-x(0); val vy1 = y(1)-y(0); - val vx0 = x(2)-x(0); val vy0 = y(2)-y(0); - - val dot00 = vx0*vx0+vy0*vy0; - val dot01 = vx0*vx1+vy0*vy1; - val dot02 = vx0*vx2+vy0*vy2; - val dot11 = vx1*vx1+vy1*vy1; - val dot12 = vx1*vx2+vy1*vy2; - val invDenom = 1.0f / (dot00*dot11 - dot01*dot01); - val u = (dot11*dot02 - dot01*dot12)*invDenom; - val v = (dot00*dot12 - dot01*dot02)*invDenom; - - return ((u>=0)&&(v>=0)&&(u+v<=1)); - } - - } diff --git a/src/org/poly2tri/MonoToneMountain.scala b/src/org/poly2tri/seidel/MonotoneMountain.scala similarity index 98% rename from src/org/poly2tri/MonoToneMountain.scala rename to src/org/poly2tri/seidel/MonotoneMountain.scala index 4e02f77..7347bc1 100644 --- a/src/org/poly2tri/MonoToneMountain.scala +++ b/src/org/poly2tri/seidel/MonotoneMountain.scala @@ -28,10 +28,12 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package org.poly2tri +package org.poly2tri.seidel import scala.collection.mutable.{ArrayBuffer, Queue} +import shapes.Point + // Doubly linked list class MonotoneMountain { diff --git a/src/org/poly2tri/Node.scala b/src/org/poly2tri/seidel/Node.scala similarity index 97% rename from src/org/poly2tri/Node.scala rename to src/org/poly2tri/seidel/Node.scala index bef7dec..ef47cd4 100644 --- a/src/org/poly2tri/Node.scala +++ b/src/org/poly2tri/seidel/Node.scala @@ -28,10 +28,12 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package org.poly2tri +package org.poly2tri.seidel import scala.collection.mutable.ArrayBuffer +import shapes.Segment + // Node for a Directed Acyclic graph (DAG) abstract class Node(var left: Node, var right: Node) { diff --git a/src/org/poly2tri/QueryGraph.scala b/src/org/poly2tri/seidel/QueryGraph.scala similarity index 98% rename from src/org/poly2tri/QueryGraph.scala rename to src/org/poly2tri/seidel/QueryGraph.scala index 2b02ed7..c9eb4ce 100644 --- a/src/org/poly2tri/QueryGraph.scala +++ b/src/org/poly2tri/seidel/QueryGraph.scala @@ -28,10 +28,12 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package org.poly2tri +package org.poly2tri.seidel import scala.collection.mutable.ArrayBuffer +import shapes.{Segment, Trapezoid} + // Directed Acyclic graph (DAG) // See "Computational Geometry", 3rd edition, by Mark de Berg et al, Chapter 6.2 diff --git a/src/org/poly2tri/Sink.scala b/src/org/poly2tri/seidel/Sink.scala similarity index 96% rename from src/org/poly2tri/Sink.scala rename to src/org/poly2tri/seidel/Sink.scala index fa6e677..c3c48a6 100644 --- a/src/org/poly2tri/Sink.scala +++ b/src/org/poly2tri/seidel/Sink.scala @@ -28,7 +28,9 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package org.poly2tri +package org.poly2tri.seidel + +import shapes.{Segment, Trapezoid} object Sink { diff --git a/src/org/poly2tri/TrapezoidalMap.scala b/src/org/poly2tri/seidel/TrapezoidalMap.scala similarity index 98% rename from src/org/poly2tri/TrapezoidalMap.scala rename to src/org/poly2tri/seidel/TrapezoidalMap.scala index 216d74e..ea907f7 100644 --- a/src/org/poly2tri/TrapezoidalMap.scala +++ b/src/org/poly2tri/seidel/TrapezoidalMap.scala @@ -28,10 +28,12 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package org.poly2tri +package org.poly2tri.seidel import scala.collection.mutable.{HashSet, ArrayBuffer} +import shapes.{Point, Segment, Trapezoid} + // See "Computational Geometry", 3rd edition, by Mark de Berg et al, Chapter 6.2 class TrapezoidalMap { diff --git a/src/org/poly2tri/Triangulator.scala b/src/org/poly2tri/seidel/Triangulator.scala similarity index 98% rename from src/org/poly2tri/Triangulator.scala rename to src/org/poly2tri/seidel/Triangulator.scala index 0247648..5bcec6f 100644 --- a/src/org/poly2tri/Triangulator.scala +++ b/src/org/poly2tri/seidel/Triangulator.scala @@ -28,10 +28,13 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package org.poly2tri +package org.poly2tri.seidel import scala.collection.mutable.ArrayBuffer +import utils.{Util, Random} +import shapes.{Point, Segment, Trapezoid} + // Based on Raimund Seidel's paper "A simple and fast incremental randomized // algorithm for computing trapezoidal decompositions and for triangulating polygons" class Triangulator(segments: ArrayBuffer[Segment]) { @@ -207,7 +210,7 @@ class Triangulator(segments: ArrayBuffer[Segment]) { // Prevents any two distinct endpoints from lying on a common vertical line, and avoiding // the degenerate case. See Mark de Berg et al, Chapter 6.3 - //val SHEER = 0.001f + //val SHEER = 0.0001f def shearTransform(point: Point) = Point(point.x + 0.0001f * point.y, point.y) } diff --git a/src/org/poly2tri/XNode.scala b/src/org/poly2tri/seidel/XNode.scala similarity index 96% rename from src/org/poly2tri/XNode.scala rename to src/org/poly2tri/seidel/XNode.scala index 1664469..481ef96 100644 --- a/src/org/poly2tri/XNode.scala +++ b/src/org/poly2tri/seidel/XNode.scala @@ -28,7 +28,9 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package org.poly2tri +package org.poly2tri.seidel + +import shapes.{Point, Segment} class XNode(point: Point, lChild: Node, rChild: Node) extends Node(lChild, rChild) { diff --git a/src/org/poly2tri/YNode.scala b/src/org/poly2tri/seidel/YNode.scala similarity index 97% rename from src/org/poly2tri/YNode.scala rename to src/org/poly2tri/seidel/YNode.scala index 5e8f45a..f6286ad 100644 --- a/src/org/poly2tri/YNode.scala +++ b/src/org/poly2tri/seidel/YNode.scala @@ -28,7 +28,9 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package org.poly2tri +package org.poly2tri.seidel + +import shapes.Segment class YNode(segment: Segment, lChild: Node, rChild: Node) extends Node(lChild, rChild) { diff --git a/src/org/poly2tri/Point.scala b/src/org/poly2tri/shapes/Point.scala similarity index 98% rename from src/org/poly2tri/Point.scala rename to src/org/poly2tri/shapes/Point.scala index 4db6156..34c174a 100644 --- a/src/org/poly2tri/Point.scala +++ b/src/org/poly2tri/shapes/Point.scala @@ -28,7 +28,7 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package org.poly2tri +package org.poly2tri.shapes case class Point(val x: Float, val y: Float) { diff --git a/src/org/poly2tri/Segment.scala b/src/org/poly2tri/shapes/Segment.scala similarity index 98% rename from src/org/poly2tri/Segment.scala rename to src/org/poly2tri/shapes/Segment.scala index 07289cd..0d032d5 100644 --- a/src/org/poly2tri/Segment.scala +++ b/src/org/poly2tri/shapes/Segment.scala @@ -28,7 +28,7 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package org.poly2tri +package org.poly2tri.shapes import scala.collection.mutable.{ArrayBuffer} diff --git a/src/org/poly2tri/Trapezoid.scala b/src/org/poly2tri/shapes/Trapezoid.scala similarity index 98% rename from src/org/poly2tri/Trapezoid.scala rename to src/org/poly2tri/shapes/Trapezoid.scala index 31ba580..77f6ded 100644 --- a/src/org/poly2tri/Trapezoid.scala +++ b/src/org/poly2tri/shapes/Trapezoid.scala @@ -28,7 +28,9 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package org.poly2tri +package org.poly2tri.shapes + +import seidel.Sink class Trapezoid(val leftPoint: Point, var rightPoint: Point, val top: Segment, val bottom: Segment) { diff --git a/src/org/poly2tri/shapes/Triangle.scala b/src/org/poly2tri/shapes/Triangle.scala new file mode 100644 index 0000000..6200883 --- /dev/null +++ b/src/org/poly2tri/shapes/Triangle.scala @@ -0,0 +1,54 @@ +package org.poly2tri.shapes + +class Triangle(var x1: Float, var y1: Float, var x2: Float, var y2: Float, var x3: Float, var y3: Float) { + + def this() = this(0,0,0,0,0,0) + + val x = new Array[Float](3) + val y = new Array[Float](3) + + // Automatically fixes orientation to ccw + + val dx1 = x2-x1 + val dx2 = x3-x1 + val dy1 = y2-y1 + val dy2 = y3-y1 + val cross = dx1*dy2-dx2*dy1 + val ccw = (cross>0) + if (ccw){ + x(0) = x1; x(1) = x2; x(2) = x3; + y(0) = y1; y(1) = y2; y(2) = y3; + } else{ + x(0) = x1; x(1) = x3; x(2) = x2; + y(0) = y1; y(1) = y3; y(2) = y2; + } + + def set(t: Triangle) { + x(0) = t.x(0) + x(1) = t.x(1) + x(2) = t.x(2) + y(0) = t.y(0) + y(1) = t.y(1) + y(2) = t.y(2) + } + + + def containsPoint(_x: Float, _y: Float): Boolean = { + + val vx2 = _x-x(0); val vy2 = _y-y(0); + val vx1 = x(1)-x(0); val vy1 = y(1)-y(0); + val vx0 = x(2)-x(0); val vy0 = y(2)-y(0); + + val dot00 = vx0*vx0+vy0*vy0; + val dot01 = vx0*vx1+vy0*vy1; + val dot02 = vx0*vx2+vy0*vy2; + val dot11 = vx1*vx1+vy1*vy1; + val dot12 = vx1*vx2+vy1*vy2; + val invDenom = 1.0f / (dot00*dot11 - dot01*dot01); + val u = (dot11*dot02 - dot01*dot12)*invDenom; + val v = (dot00*dot12 - dot01*dot02)*invDenom; + + return ((u>=0)&&(v>=0)&&(u+v<=1)); + } + + } diff --git a/src/org/poly2tri/Util.scala b/src/org/poly2tri/utils/Util.scala similarity index 97% rename from src/org/poly2tri/Util.scala rename to src/org/poly2tri/utils/Util.scala index f246f92..c7c685e 100644 --- a/src/org/poly2tri/Util.scala +++ b/src/org/poly2tri/utils/Util.scala @@ -1,8 +1,10 @@ -package org.poly2tri +package org.poly2tri.utils import scala.collection.mutable.ArrayBuffer +import shapes.Point + object Util { // From "Scala By Example," by Martin Odersky