Advertisement
Guest User

Untitled

a guest
Feb 16th, 2019
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 17.75 KB | None | 0 0
  1. package polygon;
  2. import java.util.List;
  3. import java.util.ArrayList;
  4. import java.util.PriorityQueue;
  5. import java.util.Set;
  6. import java.util.HashSet;
  7. import java.util.Comparator;
  8. import java.awt.Graphics2D;
  9. import java.awt.Color;
  10. import acp.*;
  11. import pv.*;
  12. import hull.State;
  13. import segment.Drawer;
  14. import segment.ABintersectCD;
  15.  
  16. public class Polygon {
  17. int inout = 0;
  18.  
  19. // get the inout value of the WHOLE polygon!!!
  20. int getInOut() {
  21. if (inout == 0) {
  22. Vert top = verts.get(0);
  23.  
  24. for (Vert v: verts) {
  25. if (DiffY.sign(v.p, top.p) < 0)
  26. top = v;
  27. }
  28. //Let's find if our Polygon is bounded or unbounded!!!
  29. if (top.incoming.compareTo(top.outgoing) > 0) {
  30. inout = 1;
  31. }
  32. else { // clockwise, bounded, 2
  33. inout = 2;
  34. }
  35. }
  36. return inout;
  37. }
  38.  
  39.  
  40. void copyEdge (Edge e, Vert newMaxY) {
  41. // If e.inout == 0, that's an error! You forgot to set it.
  42. if (e.inout == 0) {
  43. System.out.println("Error: Edge is not initialized");
  44. return;
  45. }
  46.  
  47. // If e.inout == 1, it's buried. Don't copy it to the output. Just return.
  48. if (e.inout == 1) {
  49. return;
  50. }
  51.  
  52. // If e.minY() is not an output vertex
  53. // replace it by an new output vertex (copy of e.minY())
  54. // (to create a copy of v use "out.new Vert(v)")
  55. // inform its edges
  56. // add it to out's list of vertices
  57.  
  58. // e.minY() is not an output vertex
  59. if ( !out.verts.contains(e.minY()) ) {
  60. System.out.println("MinY added!");
  61. Vert v = out.new Vert(e.minY());
  62. v.informEdges();
  63. out.verts.add(v);
  64. }
  65.  
  66. // Ditto e.maxY *if* newMaxY is null
  67. // Copy e using out.new Edge(e)
  68. // If newMaxY is not null, make that the copy's maxY
  69. // Add the new edge to out's list.
  70. if ( newMaxY == null ) {
  71. Vert v = out.new Vert(e.maxY());
  72. v.informEdges();
  73. out.verts.add(v);
  74. }
  75.  
  76. Edge e2 = out.new Edge(e);
  77.  
  78. if (newMaxY != null)
  79. e2.setMaxY(newMaxY);
  80.  
  81. e.informVerts();
  82. out.edges.add(e2);
  83. }
  84.  
  85. class PState implements State {
  86. int nverts; // number of verts in out to display
  87. int nedges;
  88. List<Edge> sedges = new ArrayList<Edge>(); // Sweep edges
  89. Real y;
  90. Edge a, b;
  91.  
  92. PState (Real y, Edge a, Edge b) {
  93. if (out != null)
  94. nverts = out.verts.size();
  95. if (out != null)
  96. nedges = out.edges.size();
  97. for (SweepNode n = sweep.getFirst(); n != null; n = n.getNext())
  98. sedges.add((Edge) n.getData());
  99. this.y = y;
  100. this.a = a;
  101. this.b = b;
  102. }
  103.  
  104. public void draw (Graphics2D g) {
  105. int j = 0;
  106. for (Edge e : sedges)
  107. Drawer.drawEdge(g, e.tail.p.xyz(), e.head.p.xyz(), Color.orange, "" + j++);
  108.  
  109. if (a != null)
  110. Drawer.drawEdge(g, a.tail.p.xyz(), a.head.p.xyz(), Color.red, "");
  111.  
  112. if (b != null)
  113. Drawer.drawEdge(g, b.tail.p.xyz(), b.head.p.xyz(), Color.red, "");
  114.  
  115. for (int i = 0; i < nverts; i++)
  116. Drawer.drawPoint(g, out.verts.get(i).p.xyz(), Color.black, "");
  117.  
  118. for (int i = 0; i < nedges; i++)
  119. Drawer.drawEdge(g, out.edges.get(i).tail.p.xyz(),
  120. out.edges.get(i).head.p.xyz(), Color.black, "");
  121.  
  122. if (y != null) {
  123. PV2 pm = new PV2(Real.constant(-1000), y);
  124. PV2 pp = new PV2(Real.constant(1000), y);
  125. Drawer.drawEdge(g, pm, pp, Color.blue, "");
  126. }
  127. }
  128. }
  129.  
  130. List<State> states = new ArrayList<State>();
  131.  
  132. public int numStates () { return states.size(); }
  133. public State getState (int i) { return states.get(i); }
  134.  
  135. class Vert {
  136. GO<PV2> p;
  137. Edge incoming, outgoing;
  138. Vert twin;
  139.  
  140. Vert (GO<PV2> p, Edge incoming, Edge outgoing) {
  141. this.p = p;
  142. this.incoming = incoming;
  143. this.outgoing = outgoing;
  144. }
  145.  
  146. Polygon getPolygon() { return Polygon.this; }
  147. Vert (Vert that) {
  148. this.p = that.p;
  149. this.incoming = that.incoming;
  150. this.outgoing = that.outgoing;
  151. }
  152. void informEdges() {
  153. this.incoming.head = this;
  154. this.outgoing.tail = this;
  155. }
  156.  
  157. void draw (Graphics2D g) {
  158. Drawer.drawPoint(g, p.xyz(), Color.green, "");
  159. }
  160. }
  161.  
  162. class Edge implements SweepData {
  163. int inout; // 2 if outside (not buried in) the other polygon. 1 if inside (buried).
  164. Vert tail, head;
  165. SweepNode node;
  166. Set<Edge> checked = new HashSet<Edge>();
  167.  
  168. Edge (Vert tail, Vert head) {
  169. this.tail = tail;
  170. this.head = head;
  171. }
  172.  
  173. Polygon getPolygon() { return Polygon.this; }
  174.  
  175. Edge (Edge that) {
  176. this.tail = that.tail;
  177. this.head = that.head;
  178. }
  179. void informVerts() {
  180. this.tail.outgoing = this;
  181. this.head.incoming = this;
  182. }
  183.  
  184. // Part 3: replace the current minY vertex (could be head or tail)
  185. void setMinY(Vert v) {
  186. if (this.head == this.minY())
  187. this.head = v;
  188. else
  189. this.tail = v;
  190. }
  191.  
  192. // Part 3: replace the current maxY vertex (could be head or tail)
  193. void setMaxY(Vert v) {
  194. if (this.head == this.maxY())
  195. this.head = v;
  196. else
  197. this.tail = v;
  198. }
  199.  
  200. void draw (Graphics2D g) {
  201. Drawer.drawEdge(g, tail.p.xyz(), head.p.xyz(), Color.blue, "");
  202. }
  203.  
  204. boolean intersects (Edge that) {
  205. return (AreaABC.sign(tail.p, that.tail.p, that.head.p) !=
  206. AreaABC.sign(head.p, that.tail.p, that.head.p)
  207. &&
  208. AreaABC.sign(that.tail.p, tail.p, head.p) !=
  209. AreaABC.sign(that.head.p, tail.p, head.p));
  210. }
  211.  
  212. GO<PV2> intersection (Edge that) {
  213. return new ABintersectCD(tail.p, head.p, that.tail.p, that.head.p);
  214. }
  215.  
  216. Vert minY () { return DiffY.sign(tail.p, head.p) < 0 ? tail : head; }
  217. Vert maxY () { return DiffY.sign(tail.p, head.p) > 0 ? tail : head; }
  218.  
  219. public int compareTo (SweepData data) {
  220. Edge that = (Edge) data;
  221. // EXERCISE 1
  222. // Use minY and maxY instead of tail and head.
  223. // Include the case that this and that have the same minY vertex.
  224. if(that.minY()==this.minY()){
  225. return AreaABC.sign(that.maxY().p, that.minY().p, this.maxY().p);
  226. //if(AreaABC.sign(this.minY().p,this.maxY().p,that.maxY().p)<0){
  227. //this is on the left of that
  228. // return -1;
  229. //}
  230. //else{
  231. //this is on the right of that
  232. // return 1;
  233. //}
  234. }
  235. return AreaABC.sign(that.maxY().p, that.minY().p, this.minY().p);
  236. //if(AreaABC.sign(this.minY().p,this.maxY().p,that.minY().p)<0 ){
  237. // return -1;
  238. //}
  239. //else{
  240. // return 1;
  241. //}
  242. // return 1;
  243. }
  244.  
  245. public SweepNode getNode () { return node; }
  246. public void setNode (SweepNode node) { this.node = node; }
  247. }
  248.  
  249. List<Vert> verts = new ArrayList<Vert>();
  250. List<Edge> edges = new ArrayList<Edge>();
  251.  
  252. private Polygon () {}
  253.  
  254. public Polygon (List<GO<PV2>> points) {
  255. for (GO<PV2> p : points)
  256. verts.add(new Vert(p, null, null));
  257.  
  258. Vert prev = verts.get(verts.size()-1);
  259. for (Vert v : verts) {
  260. Edge e = new Edge(prev, v);
  261. edges.add(e);
  262. e.tail.outgoing = e;
  263. e.head.incoming = e;
  264. prev = v;
  265. }
  266. }
  267.  
  268. public void draw (Graphics2D g) {
  269. for (Edge e : edges)
  270. e.draw(g);
  271. if (that != null)
  272. for (Edge e : that.edges)
  273. e.draw(g);
  274. if (out != null)
  275. for (Vert v : out.verts)
  276. v.draw(g);
  277. }
  278.  
  279. class CompareVerts implements Comparator<Vert> {
  280. public int compare (Vert a, Vert b) {
  281. return DiffY.sign(a.p, b.p);
  282. }
  283. }
  284.  
  285. Polygon that;
  286. PriorityQueue<Vert> events = new PriorityQueue<Vert>(100, new CompareVerts());
  287. SweepList sweep = new SlowList();
  288. Polygon out;
  289.  
  290. void check (SweepNode a, SweepNode b) {
  291. if (a == null || b == null)
  292. return;
  293.  
  294. Edge e = (Edge) a.getData();
  295. Edge f = (Edge) b.getData();
  296.  
  297. states.add(new PState(null, e, f));
  298.  
  299. // EXERCISE 2
  300. // Check if from same Polygon too.
  301. // Add a state after each check.
  302.  
  303. // if(e.checked.contains(f)){
  304. // System.out.println("CHECKED");
  305. // return;
  306. // }
  307.  
  308. e.checked.add(f);
  309. f.checked.add(e);
  310. if (e.getPolygon() == f.getPolygon()) {
  311. System.out.println("SAME");
  312. return;
  313. }
  314. if (!(e.intersects(f))){
  315. System.out.println("NOTINTERSECTING");
  316. return;
  317. }
  318.  
  319. System.out.println("PROCEEDING");
  320. GO<PV2> p = new ABintersectCD(e.tail.p, e.head.p, f.tail.p, f.head.p);
  321. System.out.println("intersection calculated");
  322. Vert v = out.new Vert(p, e, f);
  323. out.verts.add(v);
  324. events.add(v);
  325. states.add(new PState(null, e, f));
  326. }
  327.  
  328.  
  329.  
  330.  
  331.  
  332. public Polygon union (Polygon that) {
  333. states.clear();
  334.  
  335. for (Edge e : this.edges) {
  336. e.inout = 0;
  337. e.checked.clear();
  338. }
  339.  
  340. for (Edge e : that.edges) {
  341. e.inout = 0;
  342. e.checked.clear();
  343. }
  344.  
  345. this.that = that;
  346. out = new Polygon();
  347.  
  348. for (Vert v : this.verts)
  349. events.offer(v);
  350. for (Vert v : that.verts)
  351. events.offer(v);
  352.  
  353. while (events.size() > 0) {
  354. Vert v = events.poll();
  355. states.add(new PState(v.p.xyz().y, null, null));
  356. System.out.println("WHILING...");
  357. System.out.println("YOU BETTER FUCKING WORKING NOW!!!!!!");
  358.  
  359.  
  360. if (v.getPolygon() == out) { // \ /
  361. SweepNode iNode = v.incoming.getNode(); // / \
  362. SweepNode oNode = v.outgoing.getNode();
  363. // SweepNode iNode = sweep.add(v.incoming);
  364. // SweepNode oNode = sweep.add(v.outgoing);
  365. // System.out.println("CROSSING");
  366. // EXERCISE 3 X
  367. // v is intersection of a this edge with a that edge.
  368. states.add(new PState(v.p.xyz().y, null, null)); // repeat after swap
  369. // System.out.println(iNode);
  370. // if(iNode.getNext()!= oNode){
  371. // //System.out.println(iNode.getNext());
  372. // // System.out.println(oNode);
  373. // oNode.swapWithNext();
  374. // }
  375. // else{
  376. // iNode.swapWithNext();
  377. // }
  378.  
  379. // check(iNode.getPrevious(),iNode);
  380. // check(oNode,oNode.getNext());
  381. iNode.swapWithNext();
  382. states.add(new PState(v.p.xyz().y, null, null)); // repeat after swap
  383. check(iNode.getPrevious(),iNode);
  384. check(oNode,oNode.getNext());
  385. copyEdge(v.incoming, v);
  386. copyEdge(v.outgoing, v);
  387. //After recording the edges to be added, make the change!(change minY to new position!)
  388. v.incoming.setMinY(v);
  389. v.outgoing.setMinY(v);
  390. v.incoming.inout = 3 - v.incoming.inout;
  391. v.outgoing.inout = 3 - v.outgoing.inout;
  392.  
  393. // states.add(new PState(v.p.xyz().y, null, null));
  394.  
  395. }
  396.  
  397.  
  398. // EXERCISE 4 ^
  399. // This situation is the MOST DIFFICULT PART AMONG ALL other cases as you need to determine the
  400. // iniital correct inout values!!!
  401. else if (v.incoming.minY() == v.outgoing.minY()){
  402. // if we dont add them to sweep list, there will be NullPointer Exception
  403. SweepNode iNode = sweep.add(v.incoming);
  404. SweepNode oNode = sweep.add(v.outgoing);
  405. states.add(new PState(v.p.xyz().y, null, null)); // repeat after swap
  406. System.out.println("Meet for first time, lines ADDED");
  407.  
  408. if(iNode.getNext()!=oNode){
  409. oNode=v.incoming.node;
  410. iNode=v.outgoing.node;
  411.  
  412. // check(oNode.getPrevious(),oNode);
  413. // check(iNode,iNode.getNext());
  414.  
  415. }
  416.  
  417.  
  418.  
  419. check(iNode.getPrevious(),iNode);
  420. check(oNode,oNode.getNext());
  421. states.add(new PState(v.p.xyz().y, null, null));
  422.  
  423. // this and that are all Polygons!
  424. // Note that previously we add this and that polygons' verts to events
  425. //
  426. // for (Vert v : this.verts)
  427. // events.offer(v);
  428. // for (Vert v : that.verts)
  429. // events.offer(v);
  430. //
  431. // Now, we don't know which polygon vert(v) is from !
  432.  
  433.  
  434. if (oNode.getNext() == null) {
  435. // System.out.println("RIGHT IS NULL");
  436. if (v.getPolygon() == that) {
  437. // System.out.println("this.inout " + this.inout);
  438. v.incoming.inout = this.getInOut();
  439. v.outgoing.inout = this.getInOut();
  440. }
  441. else {
  442. // System.out.println("that.inout " + that.inout);
  443. v.incoming.inout = that.getInOut();
  444. v.outgoing.inout = that.getInOut();
  445. }
  446. }
  447. else {
  448. Edge nextEdge = (Edge) oNode.getNext().getData();
  449.  
  450. // if oNode.next is an edge from the same polygon, that means the edges
  451. // associated with the vertex(v) is from same polygon. This means
  452. // I see myself on the right, which means I should have the same inout value as
  453. // the other one I see! i.e: v's incoming and outgoing's inout should be the same as
  454. // the nextEdge we see!
  455. if (nextEdge.getPolygon() == v.getPolygon()) {
  456. v.incoming.inout = nextEdge.inout;
  457. v.outgoing.inout = nextEdge.inout;
  458. }
  459. // if not, that means oNode.next is from another polygon!
  460. else {
  461. // figure out if oNode.next is out then v is out
  462. // otherwise if oNode.next is inside, then v is inside
  463. // 1 is unbounded( drawn clockwise ), 2 is bounded ( drawn counterclockwise )
  464. // if nextEdge's minY is tail, that means the at the point we inspect, the nextEdge is
  465. // going DOWN(Note we are in Graphical Coordinate!!), which means it's clockwise -> unbounded!
  466. if (nextEdge.minY() == nextEdge.tail) {
  467. v.incoming.inout = 1; // unbounded, clockwise
  468. v.outgoing.inout = 1; // unbounded, clockwise
  469. }
  470. // else the other situation
  471. else {
  472. v.incoming.inout = 2; // bounded, counterclockwise
  473. v.outgoing.inout = 2; // bounded, counterclockwise
  474. }
  475. }
  476. }
  477. // System.out.println("incoming inout " + v.incoming.inout);
  478. // System.out.println("outgoing inout " + v.outgoing.inout);
  479.  
  480.  
  481. states.add(new PState(v.p.xyz().y, null, null)); // repeat after swap
  482.  
  483. }
  484. // EXERCISE 5 \/
  485. if (v.incoming.maxY() == v.outgoing.maxY() ){
  486. // SweepNode iNode = sweep.add(v.incoming);
  487. // SweepNode oNode = sweep.add(v.outgoing);
  488. SweepNode iNode = v.incoming.getNode();
  489. SweepNode oNode = v.outgoing.getNode();
  490. states.add(new PState(v.p.xyz().y, null, null)); // repeat after swap
  491.  
  492. if(iNode.getNext()!=oNode){
  493.  
  494. check(oNode.getPrevious(), iNode.getNext());
  495.  
  496.  
  497. }
  498. else{
  499.  
  500. check(iNode.getPrevious(), oNode.getNext());
  501.  
  502. }
  503.  
  504. // After checking, you need to change oNode pointer and make it
  505. // point to iNode
  506. // oNode.setData(v.incoming);
  507. // //iNode.setData(v.outgoing);
  508. // Remove everything, so copyEdge should not copy anything!
  509. copyEdge(v.incoming, null);
  510. copyEdge(v.outgoing, null);
  511.  
  512. iNode.remove();
  513. oNode.remove();
  514.  
  515.  
  516. states.add(new PState(v.p.xyz().y, null, null)); // repeat after swap
  517. }
  518. // EXERCISE 6 i on o
  519. if (v.incoming.maxY() == v.outgoing.minY() ){
  520. // SweepNode iNode = sweep.add(v.incoming);
  521. SweepNode iNode = v.incoming.getNode();
  522. copyEdge(v.incoming, null);
  523.  
  524. iNode.setData(v.outgoing);
  525. v.outgoing.inout = v.incoming.inout;
  526. states.add(new PState(v.p.xyz().y, null, null)); // repeat after swap
  527.  
  528. check(iNode.getPrevious(), iNode);
  529. check(iNode, iNode.getNext());
  530.  
  531. // check(iNode.getPrevious(), iNode);
  532. // check(oNode, oNode.getNext());
  533. // check(iNode.getPrevious(), oNode.getNext());
  534.  
  535. // iNode.setData(v.outgoing);
  536. // oNode.setData(v.incoming);
  537. states.add(new PState(v.p.xyz().y, null, null)); // repeat after swap
  538. }
  539. // EXERCISE 7 o on i
  540. if (v.incoming.minY() == v.outgoing.maxY() ){
  541. SweepNode oNode = v.outgoing.getNode();
  542. copyEdge(v.outgoing, null);
  543.  
  544. check(oNode.getPrevious(), oNode.getNext());
  545. // we remove oNode by setting incoming's data to oNode so that oNode is not
  546. // pointing to the original oNode we are about to remove.
  547. oNode.setData(v.incoming);
  548.  
  549. v.incoming.inout = v.outgoing.inout;
  550. states.add(new PState(v.p.xyz().y, null, null)); // repeat after swap
  551.  
  552. check(oNode.getPrevious(), oNode);
  553. check(oNode, oNode.getNext());
  554.  
  555. // remove the oNode by setting the data of oNode to iNode's data
  556.  
  557. // check(iNode.getPrevious(), iNode);
  558. // check(oNode, oNode.getNext());
  559. // check(iNode.getPrevious(), oNode.getNext());
  560. // iNode.remove();
  561. // oNode.setData(v.incoming);
  562.  
  563. states.add(new PState(v.p.xyz().y, null, null)); // repeat after swap
  564. }
  565. }
  566.  
  567.  
  568. for (Edge e : this.edges){
  569. e.checked.clear();
  570. e.inout = 0;
  571. }
  572.  
  573. for (Edge e : that.edges){
  574. e.checked.clear();
  575. e.inout = 0;
  576. }
  577.  
  578. for (Vert v: this.verts) {
  579. v.informEdges();
  580. }
  581.  
  582. for (Vert v: that.verts) {
  583. v.informEdges();
  584. }
  585.  
  586. // Part 5: Use informVerts to set out's incoming and outgoing pointers.
  587. for (Edge e: out.edges) {
  588. e.informVerts();
  589. }
  590.  
  591. // PLEASE RETURN THAT!!! NOT OUT!!! If you return OUT, you ONLY GET THE OUTPUT POINTS!!!
  592. return this;
  593. }
  594. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement