mirror of
https://github.com/jhasse/poly2tri.git
synced 2024-11-30 01:03:30 +01:00
Refactored code
This commit is contained in:
parent
3efb9622ee
commit
283886b317
@ -41,6 +41,10 @@ import org.newdawn.slick.geom.{Polygon, Circle}
|
|||||||
import scala.collection.mutable.ArrayBuffer
|
import scala.collection.mutable.ArrayBuffer
|
||||||
import scala.io.Source
|
import scala.io.Source
|
||||||
|
|
||||||
|
import seidel.Triangulator
|
||||||
|
import shapes.{Segment, Point, Triangle}
|
||||||
|
import earClip.EarClip
|
||||||
|
|
||||||
// TODO: Lots of documentation!
|
// TODO: Lots of documentation!
|
||||||
|
|
||||||
object Poly2Tri {
|
object Poly2Tri {
|
||||||
@ -103,10 +107,10 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
|
|||||||
polygon.addPoint(v.x, v.y)
|
polygon.addPoint(v.x, v.y)
|
||||||
}
|
}
|
||||||
if(!drawMap) {
|
if(!drawMap) {
|
||||||
val lCirc = new Circle(t.leftPoint.x, t.leftPoint.y, 4)
|
//val lCirc = new Circle(t.leftPoint.x, t.leftPoint.y, 4)
|
||||||
g.setColor(blue); g.draw(lCirc); g.fill(lCirc)
|
//g.setColor(blue); g.draw(lCirc); g.fill(lCirc)
|
||||||
val rCirc = new Circle(t.rightPoint.x+5, t.rightPoint.y, 4)
|
//val rCirc = new Circle(t.rightPoint.x+5, t.rightPoint.y, 4)
|
||||||
g.setColor(yellow); g.draw(rCirc); g.fill(rCirc)
|
//g.setColor(yellow); g.draw(rCirc); g.fill(rCirc)
|
||||||
}
|
}
|
||||||
g.setColor(red)
|
g.setColor(red)
|
||||||
g.draw(polygon)
|
g.draw(polygon)
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
package org.poly2tri
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ported from jBox2D. Original author: ewjordan
|
* Ported from jBox2D. Original author: ewjordan
|
||||||
* Triangulates a polygon using simple ear-clipping algorithm. Returns
|
* 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
|
* or fewer (due to pinch point polygon snipping), so allocate an array of
|
||||||
* this size.
|
* this size.
|
||||||
*/
|
*/
|
||||||
|
package org.poly2tri.earClip
|
||||||
|
|
||||||
|
import shapes.{Point, Triangle}
|
||||||
|
|
||||||
class EarClip {
|
class EarClip {
|
||||||
|
|
||||||
val tol = .001f
|
val tol = .001f
|
||||||
@ -311,56 +313,3 @@ class Poly(var x: Array[Float], var y: Array[Float], var nVertices: Int) {
|
|||||||
areaIsSet = false
|
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -28,10 +28,12 @@
|
|||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
package org.poly2tri
|
package org.poly2tri.seidel
|
||||||
|
|
||||||
import scala.collection.mutable.{ArrayBuffer, Queue}
|
import scala.collection.mutable.{ArrayBuffer, Queue}
|
||||||
|
|
||||||
|
import shapes.Point
|
||||||
|
|
||||||
// Doubly linked list
|
// Doubly linked list
|
||||||
class MonotoneMountain {
|
class MonotoneMountain {
|
||||||
|
|
@ -28,10 +28,12 @@
|
|||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
package org.poly2tri
|
package org.poly2tri.seidel
|
||||||
|
|
||||||
import scala.collection.mutable.ArrayBuffer
|
import scala.collection.mutable.ArrayBuffer
|
||||||
|
|
||||||
|
import shapes.Segment
|
||||||
|
|
||||||
// Node for a Directed Acyclic graph (DAG)
|
// Node for a Directed Acyclic graph (DAG)
|
||||||
abstract class Node(var left: Node, var right: Node) {
|
abstract class Node(var left: Node, var right: Node) {
|
||||||
|
|
@ -28,10 +28,12 @@
|
|||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
package org.poly2tri
|
package org.poly2tri.seidel
|
||||||
|
|
||||||
import scala.collection.mutable.ArrayBuffer
|
import scala.collection.mutable.ArrayBuffer
|
||||||
|
|
||||||
|
import shapes.{Segment, Trapezoid}
|
||||||
|
|
||||||
// Directed Acyclic graph (DAG)
|
// Directed Acyclic graph (DAG)
|
||||||
// See "Computational Geometry", 3rd edition, by Mark de Berg et al, Chapter 6.2
|
// See "Computational Geometry", 3rd edition, by Mark de Berg et al, Chapter 6.2
|
||||||
|
|
@ -28,7 +28,9 @@
|
|||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
package org.poly2tri
|
package org.poly2tri.seidel
|
||||||
|
|
||||||
|
import shapes.{Segment, Trapezoid}
|
||||||
|
|
||||||
object Sink {
|
object Sink {
|
||||||
|
|
@ -28,10 +28,12 @@
|
|||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
package org.poly2tri
|
package org.poly2tri.seidel
|
||||||
|
|
||||||
import scala.collection.mutable.{HashSet, ArrayBuffer}
|
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
|
// See "Computational Geometry", 3rd edition, by Mark de Berg et al, Chapter 6.2
|
||||||
|
|
||||||
class TrapezoidalMap {
|
class TrapezoidalMap {
|
@ -28,10 +28,13 @@
|
|||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
package org.poly2tri
|
package org.poly2tri.seidel
|
||||||
|
|
||||||
import scala.collection.mutable.ArrayBuffer
|
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
|
// Based on Raimund Seidel's paper "A simple and fast incremental randomized
|
||||||
// algorithm for computing trapezoidal decompositions and for triangulating polygons"
|
// algorithm for computing trapezoidal decompositions and for triangulating polygons"
|
||||||
class Triangulator(segments: ArrayBuffer[Segment]) {
|
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
|
// 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
|
// 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)
|
def shearTransform(point: Point) = Point(point.x + 0.0001f * point.y, point.y)
|
||||||
|
|
||||||
}
|
}
|
@ -28,7 +28,9 @@
|
|||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* 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) {
|
class XNode(point: Point, lChild: Node, rChild: Node) extends Node(lChild, rChild) {
|
||||||
|
|
@ -28,7 +28,9 @@
|
|||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* 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) {
|
class YNode(segment: Segment, lChild: Node, rChild: Node) extends Node(lChild, rChild) {
|
||||||
|
|
@ -28,7 +28,7 @@
|
|||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* 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) {
|
case class Point(val x: Float, val y: Float) {
|
||||||
|
|
@ -28,7 +28,7 @@
|
|||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
package org.poly2tri
|
package org.poly2tri.shapes
|
||||||
|
|
||||||
import scala.collection.mutable.{ArrayBuffer}
|
import scala.collection.mutable.{ArrayBuffer}
|
||||||
|
|
@ -28,7 +28,9 @@
|
|||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* 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) {
|
class Trapezoid(val leftPoint: Point, var rightPoint: Point, val top: Segment, val bottom: Segment) {
|
||||||
|
|
54
src/org/poly2tri/shapes/Triangle.scala
Normal file
54
src/org/poly2tri/shapes/Triangle.scala
Normal file
@ -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));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,8 +1,10 @@
|
|||||||
|
|
||||||
package org.poly2tri
|
package org.poly2tri.utils
|
||||||
|
|
||||||
import scala.collection.mutable.ArrayBuffer
|
import scala.collection.mutable.ArrayBuffer
|
||||||
|
|
||||||
|
import shapes.Point
|
||||||
|
|
||||||
object Util {
|
object Util {
|
||||||
|
|
||||||
// From "Scala By Example," by Martin Odersky
|
// From "Scala By Example," by Martin Odersky
|
Loading…
Reference in New Issue
Block a user