public TrapezoidLine(TDPoint a_start, TDPoint a_end) { start = a_start; end = a_end; length = Mathf.Abs(start.y - end.y); up = (start.y - end.y > 0); }
public TrapezoidLine(float x1, float y1, float x2, float y2) { start = new TDPoint(x1, y1); end = new TDPoint(x2, y2); length = Mathf.Abs(y1 - y2); up = (y1 - y2 > 0); }
//compute the faces intersect with segment seg private List <TrapezoidFace> FollowSegment(TDShape seg) { List <TrapezoidFace> traversed = new List <TrapezoidFace>(); TDPoint p = seg.getFirst(); TDPoint q = seg.getLast(); /* if (p.equals(q)) * System.out.println("AAAAAAHHHH!"); */ TrapezoidFace start = Dgraph.retrieve(p); traversed.Add(start); TrapezoidFace j = start; while (j != null && (j.rightp != null && q.right(j.rightp))) { if (seg.above(j.rightp)) { j = j.lowerRight; } else { j = j.upperRight; } if (j != null) { traversed.Add(j); } } return(traversed); }
public TrapezoidLine(float a_x, float a_y, float a_length, bool a_up) { start = new TDPoint(a_x, a_y); end = new TDPoint(a_x, a_up ? a_y - a_length : a_y + a_length); length = a_length; up = a_up; }
public TrapezoidLine(TDPoint a_start, float a_length, bool a_up) { //super(); start = a_start; length = a_length; up = a_up; end = new TDPoint(start.x, up ? start.y - length : start.y + length); }
public float intersect(TDPoint pt) { float x1 = getFirst().x; float y1 = getFirst().y; float x2 = getLast().x; float y2 = getLast().y; return(Mathf.Round(lineAprox(x1, y1, x2, y2, pt.x))); }
public TrapezoidFace retrieve(TDPoint p) { TDNode nextNode = root; while (nextNode.getType() != TDNode.LEAF) { nextNode = nextNode.getNext(p); } return(nextNode.t); }
void Awake() { p = null; s = null; t = null; parent = null; leftNode = null; rightNode = null; }
public TrapezoidFace(TDShape atop, TDShape abottom, TDPoint aleftp, TDPoint arightp, TrapezoidFace aupperLeft, TrapezoidFace alowerLeft, TrapezoidFace aupperRight, TrapezoidFace alowerRight) { top = atop; bottom = abottom; leftp = aleftp; rightp = arightp; upperLeft = aupperLeft; lowerLeft = alowerLeft; upperRight = aupperRight; lowerRight = alowerRight; }
public TrapezoidFace(TDShape atop, TDShape abottom, TDPoint aleftp, TDPoint arightp) { top = atop; bottom = abottom; leftp = aleftp; rightp = arightp; upperLeft = null; lowerLeft = null; upperRight = null; lowerRight = null; }
public TrapezoidFace() { top = null; bottom = null; leftp = null; rightp = null; upperLeft = null; lowerLeft = null; upperRight = null; lowerRight = null; }
public TDNode getNext(TDPoint p) { // x-node if (type == POINT) { return(p.right(p) ? rightNode : leftNode); } // y-node else if (type == SEG) { return(s.above(p) ? leftNode : rightNode); } return(null); }
public bool below(TDPoint p) { if (contains(p)) { return(false); } // Assume that p is within the proper x coords of the shape float x1 = getFirst().x; float x2 = getLast().x; float y1 = getFirst().y; float y2 = getLast().y; return(p.y > lineAprox(x1, y1, x2, y2, p.x)); }
/* Intersect the given trapezoidal line with * all other lines in this shape. */ public float intersect(TrapezoidLine t, float max) { float min = max; foreach (TDPoint pt in points) { if (points.IndexOf(pt) > 0) { TDPoint prevpt = points[points.IndexOf(pt) - 1]; if (consider(t.getStart(), pt, prevpt)) { min = Mathf.Min(min, (float )(pt.y - prevpt.y) / (pt.x - prevpt.x) * (t.getStart().x - prevpt.x) + prevpt.y); } } } return(min); }
public TDNode retrieveNode(TDPoint p) { //Debug.Log("Retrieving p=("+p.x+","+p.y+")"); TDNode nextNode = root; int steps = 0; String s = ""; while (nextNode.getType() != TDNode.LEAF) { //Debug.Log( s+nextNode.print()); nextNode = nextNode.getNext(p); steps++; s = s + " "; } //Debug.Log("Steps: "+steps); return(nextNode); }
public bool right(TDPoint p) { return(x >= p.x); }
/* * Creates trapezoidal maps the "naive" way. More specifically, this * function iterates through each shape, and each point of each shape, * creating a TrapezoidLine for each point with an initially long length. * Then, this length is minimized over all the x intersections for above the * point. This is repeated for all the lines below the point. This is * primarily used for drawing the visual lines on the screen (as any time * savings are already negated when having to draw all objects anyway). */ public List <TrapezoidLine> naiveMap(float width, float height) { //return all the vertical lines of trapezoid. //TODO:fix the boundary parameter; List <TrapezoidLine> trapezoidMap = new List <TrapezoidLine>(); // Add the borders of the window as temporary shapes TDShape border = new TDShape(); TDShape border2 = new TDShape(); border.getPoints().Add(new TDPoint(-1f * height, 0)); border.getPoints().Add(new TDPoint(height, 0)); border2.getPoints().Add(new TDPoint(0, -1f * width)); border2.getPoints().Add(new TDPoint(0, width)); shapes.Add(border); shapes.Add(border2); // Step through each shape for (int i = 0; i < shapes.Count; i++) { //TDShape s = shapes[i]; //TDShape sh = shapes[i + 1]; TDShape sh = shapes[i]; // Ignore the border shapes so their points do not appear as part of // the trapezoidal map if (sh.equals(border) || sh.equals(border2)) { continue; } // Step through the points in the current shape for (int pi = 0; pi < sh.getPoints().Count; pi++) { //TDPoint p = sh.getPoints()[pi]; TDPoint pt = sh.getPoints()[pi]; // Generate two trapezoidal lines for each point (up and down) TrapezoidLine t = new TrapezoidLine(pt, height + 1, true); TrapezoidLine t2 = new TrapezoidLine(pt, height + 1, false); bool tu = false; bool t2u = false; // Iterate over all shapes, intersecting the trapezoidal lines // with each of the shapes for (int s2i = 0; s2i < shapes.Count; s2i++) { //TDShape s2 = shapes[s2i]; TDShape sh2 = shapes[s2i]; // if(!sh.equals(sh2)) { // If the intersection yields a positive difference that is // smaller than the previous length, update t // down if (t.getStart().y - sh2.intersect(t, height + 1) > 0) { t.setLength(Mathf.Min((t.getStart().y - sh2 .intersect(t, height + 1)), t.getLength())); tu = true; } // if the intersection yields a negative difference that is // absolutely smaller than the previous length, update t2 else if (t2.getStart().y - sh2.intersect(t2, height + 1) < 0) { t2.setLength(Mathf.Min(Mathf.Abs(t2.getStart().y - sh2.intersect(t2, height + 1)), t2 .getLength())); t2u = true; } // } } // If the lengths have been updated to a reasonable value, Add // them if (t.getLength() < height) { trapezoidMap.Add(t); } if (t2.getLength() < height) { trapezoidMap.Add(t2); } } } // Remove the borders so they are not displayed shapes.Remove(border); shapes.Remove(border2); return(trapezoidMap); }
public void setLeft(TDPoint a_leftp) { leftp = a_leftp; }
public void setRight(TDPoint a_rightp) { rightp = a_rightp; }
public TrapezoidLine() { length = 0; start = new TDPoint(); end = new TDPoint(); }
public void draw(Graphics g, float width, float height) { // Point classification: //1. Leftp is in top, rightp is in bottom // 2. Leftp is in top, rightp is in neither // * 3. Leftp is in bottom, rightp is in neither // * 4. Leftp is in bottom, rightp is in top // * 5. Rightp is in top, leftp is in bottom // * 6. Rightp is in top, leftp is in neither // * 7. Rightp is in bottom, leftp is in neither // * 8. Rightp is in bottom, leftp is in top // * 9. Leftp is in top, rightp is in top // * 10.Leftp is in bottom, rightp is in bottom TDPoint l = new TDPoint(0f, 0f); TDPoint r = new TDPoint(width, height); if (leftp != null) { l.x = leftp.x; l.y = leftp.y; } if (rightp != null) { r.x = rightp.x; r.y = rightp.y; } if (l.x > r.x) { float tx = l.x; float ty = l.y; l.x = r.x; l.y = r.y; r.x = tx; r.y = ty; } if (top == null) { r.y = 0; } if (bottom == null) { l.y = height; } /* * if(selected) g.setColor(Color.green); * g.drawString("" + index,(r.x+l.x)/2,(r.y+l.y)/2); * g.setColor(Color.blue); */ //[TODO]TO CHECK: is this draw a face? /* * if(top!=null) { * g.drawLine(l.x,l.y,l.x,top.intersect(l)); * g.drawLine(r.x,r.y,r.x,top.intersect(r)); * } * else { * g.drawLine(l.x,l.y,l.x,0); * g.drawLine(r.x,r.y,r.x,0); * } * if(bottom!=null) { * g.drawLine(l.x,l.y,l.x,bottom.intersect(l)); * g.drawLine(r.x,r.y,r.x,bottom.intersect(r)); * } * else { * g.drawLine(l.x,l.y,l.x,height); * g.drawLine(r.x,r.y,r.x,height); * * } */ }
public TDNode(TDPoint _p) { p = _p; type = POINT; }
public bool equals(TDPoint p) { return((p.x == x) && (p.y == y)); }
public bool contains(TDPoint pt) { return(points.Contains(pt)); }
private bool consider(TDPoint a, TDPoint b, TDPoint c) { return((a.x > b.x && a.x < c.x) || (a.x > c.x && a.x < b.x) /* && (a.y > b.y || a.y > c.y) */); }
public void setStart(TDPoint a_start) { start = a_start; }
//point location public void retrievePoint(TDPoint p) { Dgraph.retrieveNode(p).t.selected = true; // System.out.println("Point retrieved"); }
public void setEnd(TDPoint a_end) { end = a_end; length = Mathf.Abs(start.y - end.y); up = (start.y - end.y > 0); }
//Do increamental construction, return built faces public List <TrapezoidFace> incrementalMap() { int i; // Set<TrapezoidLine> trapezoidMap = new List<TrapezoidLine>(); List <TrapezoidFace> trapezoidFaces = new List <TrapezoidFace>(); List <TDShape> segments = new List <TDShape>(shapes); /* int index = 0; * for (Shape s : segments) { * s.index = index; * index++; * } */ // T(nil) TrapezoidFace nilFace = new TrapezoidFace(); trapezoidFaces.Add(nilFace); // Add T(nil) to D // Graph Dgraph = new Graph(); Dgraph = new TDGraph(); Dgraph.Add(new TDNode(nilFace)); // Debug // Dgraph.traverseTree(); while (segments.Count > 0) { TDShape seg = randomShape(segments); segments.Remove(seg); // System.out.println("Segment: "+seg.index); List <TrapezoidFace> intersectedFaces = FollowSegment(seg); // System.out.println("Intersected: " + intersectedFaces.size()); TDPoint p = seg.getFirst(); TDPoint q = seg.getLast(); if (intersectedFaces.Count == 1) { //segment lies within 1 face, split this face; TrapezoidFace d = intersectedFaces[0]; trapezoidFaces.Remove(d); TrapezoidFace A = new TrapezoidFace(d.top, d.bottom, d.leftp, p); TrapezoidFace C = new TrapezoidFace(d.top, seg, p, q); TrapezoidFace D = new TrapezoidFace(seg, d.bottom, p, q); TrapezoidFace B = new TrapezoidFace(d.top, d.bottom, q, d.rightp); A.setNeighbors(d.upperLeft, d.lowerLeft, C, D); C.setNeighbors(A, A, B, B); D.setNeighbors(A, A, B, B); B.setNeighbors(C, D, d.upperRight, d.lowerRight); if (d.upperLeft != null) { d.upperLeft.upperRight = A; d.upperLeft.lowerRight = A; } if (d.lowerLeft != null) { d.lowerLeft.upperRight = A; d.lowerLeft.lowerRight = A; } if (d.upperRight != null) { d.upperRight.upperLeft = B; d.upperRight.lowerLeft = B; } if (d.lowerRight != null) { d.lowerRight.upperLeft = B; d.lowerRight.lowerLeft = B; } trapezoidFaces.Add(A); trapezoidFaces.Add(B); trapezoidFaces.Add(C); trapezoidFaces.Add(D); TDNode subRoot = d.n; // Dgraph.retrieveNode(p); // Switch node over subRoot.t = null; subRoot.setType(TDNode.POINT); subRoot.p = p; // Set left node subRoot.leftNode = new TDNode(A); subRoot.leftNode.parent = subRoot; // Set right tree subRoot.rightNode = new TDNode(q); subRoot.rightNode.parent = subRoot; subRoot.rightNode.rightNode = new TDNode(B); subRoot.rightNode.rightNode.parent = subRoot.rightNode; subRoot.rightNode.leftNode = new TDNode(seg); subRoot.rightNode.leftNode.parent = subRoot.rightNode; subRoot.rightNode.leftNode.leftNode = new TDNode(C); subRoot.rightNode.leftNode.leftNode.parent = subRoot.rightNode.leftNode; subRoot.rightNode.leftNode.rightNode = new TDNode(D); subRoot.rightNode.leftNode.rightNode.parent = subRoot.rightNode.leftNode; } else { i = 0; List <TrapezoidFace> newFaces = new List <TrapezoidFace>(); TrapezoidFace prevUpper = null; TrapezoidFace prevLower = null; foreach (TrapezoidFace d in intersectedFaces) { // if(!trapezoidFaces.contains(d)) System.out.println("AAAAAHHHHHHHHH!!!!"); //Intersect with multiple faces // First if (i == 0) { trapezoidFaces.Remove(d); TrapezoidFace A = new TrapezoidFace(d.top, d.bottom, d.leftp, p); TrapezoidFace B = new TrapezoidFace(d.top, seg, p, d.rightp); TrapezoidFace C = new TrapezoidFace(seg, d.bottom, p, d.rightp); A.setNeighbors(d.upperLeft, d.lowerLeft, B, C); B.setNeighbors(A, A, null, null); C.setNeighbors(A, A, null, null); if (d.upperLeft != null) { //if(d.upperLeft.lowerRight==d.upperLeft.upperRight) d.upperLeft.upperRight = A; d.upperLeft.lowerRight = A; } if (d.lowerLeft != null) { //if(d.lowerLeft.upperRight==d.upperLeft.upperRight) d.lowerLeft.lowerRight = A; d.lowerLeft.upperRight = A; } trapezoidFaces.Add(A); newFaces.Add(B); newFaces.Add(C); prevUpper = B; prevLower = C; TDNode subRoot = d.n; // Dgraph.retrieveNode(p); subRoot.t = null; subRoot.setType(TDNode.POINT); subRoot.p = p; // Set left node subRoot.leftNode = new TDNode(A); subRoot.leftNode.parent = subRoot; // Set right tree subRoot.rightNode = new TDNode(seg); subRoot.rightNode.parent = subRoot; subRoot.rightNode.leftNode = new TDNode(B); subRoot.rightNode.leftNode.parent = subRoot.rightNode; subRoot.rightNode.rightNode = new TDNode(C); subRoot.rightNode.rightNode.parent = subRoot.rightNode; foreach (TrapezoidFace e in trapezoidFaces) { if (!trapezoidFaces.Contains(e.upperLeft)) { e.upperLeft = null; } if (!trapezoidFaces.Contains(e.lowerLeft)) { e.lowerLeft = null; } if (!trapezoidFaces.Contains(e.upperRight)) { e.upperRight = null; } if (!trapezoidFaces.Contains(e.lowerRight)) { e.lowerRight = null; } } } // Last else if (i == intersectedFaces.Count - 1) { trapezoidFaces.Remove(d); TrapezoidFace B = new TrapezoidFace(d.top, seg, d.leftp, q); TrapezoidFace C = new TrapezoidFace(seg, d.bottom, d.leftp, q); TrapezoidFace A = new TrapezoidFace(d.top, d.bottom, q, d.rightp); B.setNeighbors(prevUpper, prevUpper, A, A); C.setNeighbors(prevLower, prevLower, A, A); A.setNeighbors(B, C, d.upperRight, d.lowerRight); prevUpper.upperRight = B; prevUpper.lowerRight = B; prevLower.upperRight = C; prevLower.lowerRight = C; if (d.upperRight != null) { //if(d.upperRight.upperLeft==d.upperRight.lowerLeft) d.upperRight.upperLeft = A; d.upperRight.lowerLeft = A; } if (d.lowerRight != null) { //if(d.lowerRight.upperLeft==d.lowerRight.lowerLeft) d.lowerRight.lowerLeft = A; d.lowerRight.upperLeft = A; } trapezoidFaces.Add(A); newFaces.Add(B); newFaces.Add(C); TDNode subRoot = d.n; // Dgraph.retrieveNode(q); subRoot.t = null; subRoot.setType(TDNode.POINT); subRoot.p = q; // Set right node subRoot.rightNode = new TDNode(A); subRoot.rightNode.parent = subRoot; // Set left node subRoot.leftNode = new TDNode(seg); subRoot.leftNode.parent = subRoot; subRoot.leftNode.leftNode = new TDNode(B); subRoot.leftNode.leftNode.parent = subRoot.leftNode; subRoot.leftNode.rightNode = new TDNode(C); subRoot.leftNode.rightNode.parent = subRoot.leftNode; foreach (TrapezoidFace e in trapezoidFaces) { if (!trapezoidFaces.Contains(e.upperLeft)) { e.upperLeft = null; } if (!trapezoidFaces.Contains(e.lowerLeft)) { e.lowerLeft = null; } if (!trapezoidFaces.Contains(e.upperRight)) { e.upperRight = null; } if (!trapezoidFaces.Contains(e.lowerRight)) { e.lowerRight = null; } } } // Middle else { trapezoidFaces.Remove(d); TrapezoidFace A = new TrapezoidFace(d.top, seg, d.leftp, d.rightp); TrapezoidFace B = new TrapezoidFace(seg, d.bottom, d.leftp, d.rightp); A.setNeighbors(prevUpper, prevUpper, null, null); B.setNeighbors(prevLower, prevLower, null, null); prevUpper.upperRight = A; prevUpper.lowerRight = A; prevLower.upperRight = B; prevLower.lowerRight = B; prevUpper = A; prevLower = B; newFaces.Add(A); newFaces.Add(B); TDNode subRoot = d.n; subRoot.t = null; subRoot.setType(TDNode.SEG); subRoot.s = seg; // Set left node subRoot.leftNode = new TDNode(A); subRoot.leftNode.parent = subRoot; subRoot.rightNode = new TDNode(B); subRoot.rightNode.parent = subRoot; foreach (TrapezoidFace e in trapezoidFaces) { if (!trapezoidFaces.Contains(e.upperLeft)) { e.upperLeft = null; } if (!trapezoidFaces.Contains(e.lowerLeft)) { e.lowerLeft = null; } if (!trapezoidFaces.Contains(e.upperRight)) { e.upperRight = null; } if (!trapezoidFaces.Contains(e.lowerRight)) { e.lowerRight = null; } } } i++; } bool allMerged = false; // System.out.println("New before merge: " + newFaces.size()); // Merge trapezoids while (!allMerged) { foreach (TrapezoidFace d in newFaces) { if (d.rightp != null && !d.rightp.equals(p) && !d.rightp.equals(q) && ((d.top != null && (d.top.above(d.rightp))) || (d.bottom != null && (d.bottom.below(d.rightp))))) { TrapezoidFace next = d.upperRight; // Either should work d.upperRight = next.upperRight; d.lowerRight = next.lowerRight; if ((d.top != null && (d.top.above(d.rightp)))) { d.upperRight.lowerLeft = d; } else { d.upperRight.upperLeft = d; } d.rightp = next.rightp; // Update the node tree as well if (next.n.parent.isLeftNode(next.n)) { next.n.parent.leftNode = d.n; } else { next.n.parent.rightNode = d.n; } newFaces.Remove(next); //System.out.println("Removed?: "+ newFaces.Remove(next)); break; } else { d.merged = true; } } allMerged = true; foreach (TrapezoidFace d in newFaces) { if (!d.merged) { allMerged = false; } } } // System.out.println("New after merge: " + newFaces.size()); foreach (TrapezoidFace d in newFaces) { d.merged = false; // d.selected=true; trapezoidFaces.Add(d); } } /* for(TrapezoidFace d : trapezoidFaces) { * if(!(trapezoidFaces.contains(d.upperLeft) || d.upperLeft==null) || * !(trapezoidFaces.contains(d.upperRight) || d.upperRight==null ) || * !(trapezoidFaces.contains(d.lowerLeft) || d.lowerLeft==null ) || * !(trapezoidFaces.contains(d.lowerRight) || d.lowerRight==null) ) * System.out.println("Sanity check failed"); * } */ } int j = 0; foreach (TrapezoidFace f in trapezoidFaces) { f.setIndex(j); j++; } Dgraph.traverseTree(); // System.out.println("----"); return(trapezoidFaces); }