import java.awt.Graphics; import java.awt.Polygon; public class Face { public Vertex vertex; public Segment segment; public Face prev; public Face next; public Face twin; public Face() { } public Face(Vertex v) { this.vertex = v; } public Face(int x, int y, int w, int h) { this.addVertex(new Vertex(x , y )); this.addVertex(new Vertex(x , y+h)); this.addVertex(new Vertex(x+w, y+h)); this.addVertex(new Vertex(x+w, y )); } public void draw(Graphics g) { Face cur_face = this; do { cur_face.segment.h.draw(g); cur_face = cur_face.next; } while (cur_face != this); } public void fill(Graphics g) { Polygon poly = new Polygon(); Face cur_face = this; do { poly.addPoint((int) cur_face.vertex.x, (int) cur_face.vertex.y); cur_face = cur_face.next; } while (cur_face != this); g.fillPolygon(poly); } public Segment clip(Segment s) { // returns the part of contained in Face cur_face = this; do { s = s.clip(cur_face.segment.h); cur_face = cur_face.next; } while (cur_face != this && s != null); return s; } public Face[] split(Segment s) { // return the two halves of after it is split by // faces[0] = in front part // faces[1] = in back part Face [] faces = new Face[2]; faces[0] = new Face(); faces[1] = new Face(); int left_vertices = 0; int right_vertices = 0; // traverse all segments, clip to the halfspace of Face cur_face = this; do { int e1 = s.h.eval(cur_face.vertex); // check where to put the first vertex if (e1 == Parameters.IN_FRONT || e1 == Parameters.COINCIDENT) { faces[0].addVertex(cur_face.vertex); left_vertices++; } if (e1 == Parameters.IN_BACK || e1 == Parameters.COINCIDENT) { faces[1].addVertex(cur_face.vertex); right_vertices++; } // if the segment is spanning introduce new vertices if (s.h.eval(cur_face.segment) == Parameters.SPANNING) { Vertex new_vertex = cur_face.segment.intersect(s); faces[0].addVertex(new_vertex); left_vertices++; faces[1].addVertex(new_vertex); right_vertices++; } cur_face = cur_face.next; } while (cur_face != this); if (left_vertices < 3) faces[0] = null; if (right_vertices < 3) faces[1] = null; return faces; } public void addVertex(Vertex v) { if (this.vertex == null) { this.vertex = v; this.prev = this; this.next = this; this.twin = new Face(this.vertex); } else { Face new_face = new Face(v); // link the prev side of the new entry new_face.prev = this.prev; this.prev.next = new_face; // link the next side of the new entry new_face.next = this; this.prev = new_face; // recompute the edges new_face.prev.segment = new Segment(new_face.prev.vertex, new_face.vertex); new_face.segment = new Segment(new_face.vertex, new_face.next.vertex); // now do everything for the twins // create them: new_face.twin = new Face(new_face.next.vertex); new_face.twin.segment = new Segment(new_face.next.vertex, new_face.vertex); new_face.prev.twin.vertex = new_face.vertex; new_face.prev.twin.segment = new Segment(new_face.vertex, new_face.prev.vertex); // link them: new_face.twin.prev = new_face.next.twin; new_face.next.twin.next = new_face.twin; new_face.twin.next = new_face.prev.twin; new_face.prev.twin.prev = new_face.twin; } } }