Refactored code

This commit is contained in:
masongreen 2009-07-26 16:01:33 -04:00
parent 3efb9622ee
commit 283886b317
15 changed files with 100 additions and 72 deletions

View File

@ -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)

View File

@ -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));
}
}

View File

@ -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 {

View File

@ -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) {

View File

@ -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

View File

@ -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 {

View File

@ -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 {

View File

@ -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)
} }

View File

@ -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) {

View File

@ -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) {

View File

@ -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) {

View File

@ -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}

View File

@ -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) {

View 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));
}
}

View File

@ -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