Advertisement
bekovski

algovi_sat_2

Jun 13th, 2018
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 26.41 KB | None | 0 0
  1. import java.awt.Color;
  2. import java.awt.Font;
  3. import java.util.ArrayList;
  4. import java.util.List;
  5.  
  6. import algoanim.animalscript.AnimalCircleGenerator;
  7. import algoanim.animalscript.AnimalPointGenerator;
  8. import algoanim.animalscript.AnimalPolylineGenerator;
  9. import algoanim.animalscript.AnimalRectGenerator;
  10. import algoanim.animalscript.AnimalScript;
  11. import algoanim.animalscript.AnimalTextGenerator;
  12. import algoanim.animalscript.AnimalTriangleGenerator;
  13. import algoanim.primitives.Circle;
  14. import algoanim.primitives.Point;
  15. import algoanim.primitives.Polyline;
  16. import algoanim.primitives.Rect;
  17. import algoanim.primitives.SourceCode;
  18. import algoanim.primitives.Text;
  19. import algoanim.primitives.Triangle;
  20. import algoanim.primitives.generators.Language;
  21. import algoanim.properties.AnimationPropertiesKeys;
  22. import algoanim.properties.CircleProperties;
  23. import algoanim.properties.PointProperties;
  24. import algoanim.properties.PolylineProperties;
  25. import algoanim.properties.RectProperties;
  26. import algoanim.properties.SourceCodeProperties;
  27. import algoanim.properties.TextProperties;
  28. import algoanim.properties.TriangleProperties;
  29. import algoanim.util.Coordinates;
  30. import algoanim.util.Node;
  31. import algoanim.util.TicksTiming;
  32. import algoanim.util.Timing;
  33. import auxiliary.Vector2f;
  34.  
  35. public class SAT {
  36.    
  37.     public static final Color LINE_DEFAULT_COLOR    = Color.BLACK;
  38.     public static final Color VECTOR_DEFAULT_COLOR  = Color.RED;
  39.    
  40.     Language lang;
  41.    
  42.     Text text;
  43.     Point point;
  44.     Circle circle;
  45.     Polyline line;
  46.     Polyline edge;
  47.     Polyline vector;
  48.     Polyline separatingAxis;
  49.     Triangle triangle;
  50.    
  51.     // temp
  52.     Polyline[] vectors = new Polyline[3];
  53.    
  54.     SourceCode sc;
  55.     Timing timing;
  56.    
  57.     // might need these properties
  58.     TextProperties textProps;
  59.     RectProperties rectProps;
  60.     PointProperties pointProps;
  61.     CircleProperties circleProps;
  62.     PolylineProperties lineProps;
  63.     PolylineProperties vectorProps;
  64.     TriangleProperties triangleProps;
  65.    
  66.    
  67.     int x = 40;
  68.     int y = 140;
  69.     int startY;
  70.     int offsetY = 20;
  71.     String vertexName;
  72.     String neighbor1Name;
  73.     String neighbor2Name;
  74.    
  75.     List<Text> textList = new ArrayList<>();
  76.    
  77.     public void init() {
  78.         lang = new AnimalScript("Separating Axis Theorem (Circle-Triangle)", "Bekir Oezkara", 640, 480);
  79.         lang.setStepMode(true);
  80.        
  81.         timing = new TicksTiming(200);
  82.        
  83.         textProps = new TextProperties();
  84.         textProps.set(AnimationPropertiesKeys.COLOR_PROPERTY, Color.BLACK);
  85.         textProps.set(AnimationPropertiesKeys.FONT_PROPERTY, new Font("Monospaced", Font.PLAIN, 12));
  86.        
  87.         rectProps = new RectProperties();
  88.         rectProps.set(AnimationPropertiesKeys.COLOR_PROPERTY, Color.DARK_GRAY);
  89.         rectProps.set(AnimationPropertiesKeys.FILLED_PROPERTY, true);
  90.         rectProps.set(AnimationPropertiesKeys.FILL_PROPERTY, Color.LIGHT_GRAY);
  91.         rectProps.set(AnimationPropertiesKeys.DEPTH_PROPERTY, 2);
  92.        
  93.         pointProps = new PointProperties();
  94.         pointProps.set(AnimationPropertiesKeys.COLOR_PROPERTY, Color.CYAN);
  95.        
  96.         circleProps = new CircleProperties();
  97. //      circleProps.set(AnimationPropertiesKeys.COLOR_PROPERTY, Color.RED);
  98.         circleProps.set(AnimationPropertiesKeys.FILL_PROPERTY, Color.WHITE);
  99.        
  100.         lineProps = new PolylineProperties();
  101.         lineProps.set(AnimationPropertiesKeys.COLOR_PROPERTY, LINE_DEFAULT_COLOR);
  102.        
  103.         vectorProps = new PolylineProperties();
  104.         vectorProps.set(AnimationPropertiesKeys.COLOR_PROPERTY, VECTOR_DEFAULT_COLOR);
  105.         vectorProps.set(AnimationPropertiesKeys.FWARROW_PROPERTY, true);
  106.        
  107.         triangleProps = new TriangleProperties();
  108. //      triangleProps.set(AnimationPropertiesKeys.COLOR_PROPERTY, Color.GREEN);
  109.         triangleProps.set(AnimationPropertiesKeys.FILL_PROPERTY, Color.WHITE);
  110.        
  111.         makeHeader();
  112.         makeSideBox();
  113.         drawCoordSystem();
  114.        
  115.     }
  116.    
  117.    
  118.     public boolean hasSA(auxiliary.Circle circle, auxiliary.Triangle triangle) {
  119.        
  120.         makeCircle(circle.center.x, circle.center.y, circle.radius);
  121.         makeTriangle(triangle.A, triangle.B, triangle.C);
  122.         lang.nextStep();
  123.        
  124.         x = 910;
  125.         startY = 160;
  126.         y = startY;
  127.        
  128.         // vertices
  129.         showSourceCodeVertexSA();
  130.         Circle vertexHighlightCircle;
  131.         boolean isFilled = true;
  132.        
  133.         vertexName = "A";
  134.         neighbor1Name = "B";
  135.         neighbor2Name = "C";
  136.         vertexHighlightCircle = makeCircle(triangle.A.x, triangle.A.y, 0.1f, Color.PINK, isFilled);
  137.         textAndStep("Vertex A");
  138.         vertexHighlightCircle.hide();
  139.         boolean separatedByVertexA = isVertexSA(circle, triangle, triangle.A);
  140.        
  141.         clearText();
  142.         y = startY;
  143.        
  144.         vertexName = "B";
  145.         neighbor1Name = "A";
  146.         neighbor2Name = "C";
  147.         vertexHighlightCircle = makeCircle(triangle.B.x, triangle.B.y, 0.1f, Color.PINK, isFilled);
  148.         textAndStep("Vertex B");
  149.         vertexHighlightCircle.hide();
  150.         boolean separatedByVertexB = isVertexSA(circle, triangle, triangle.B);
  151.        
  152.         clearText();
  153.         y = startY;
  154.        
  155.         vertexName = "C";
  156.         neighbor1Name = "A";
  157.         neighbor2Name = "B";
  158.         vertexHighlightCircle = makeCircle(triangle.C.x, triangle.C.y, 0.1f, Color.PINK, isFilled);
  159.         textAndStep("Vertex C");
  160.         vertexHighlightCircle.hide();
  161.         boolean separatedByVertexC = isVertexSA(circle, triangle, triangle.C);
  162.        
  163.         clearText();
  164.         y = startY;
  165.        
  166.         // edges
  167.         // sc.changeColor("", Color.WHITE, null, null);
  168.         // showSourceCodeEdgeSA();
  169.        
  170.         edge = makeLine(triangle.A, triangle.B, false, true);
  171.         edge.changeColor("", Color.PINK, null, null);
  172.         textAndStep("Edge from A to B");
  173.         boolean separatedByEdgeAB = isEdgeSA(circle, triangle, triangle.edgeAB, triangle.A, triangle.B, triangle.C);
  174.         edge.hide();
  175.        
  176.         clearText();
  177.         y = startY;
  178.        
  179.         edge = makeLine(triangle.A, triangle.C, false, true);
  180.         edge.changeColor("", Color.PINK, null, null);
  181.         textAndStep("Edge from A to C");
  182.         boolean separatedByEdgeAC = isEdgeSA(circle, triangle, triangle.edgeAC, triangle.A, triangle.C, triangle.B);
  183.         edge.changeColor("", Color.BLACK, null, null);
  184.        
  185.         clearText();
  186.         y = startY;
  187.        
  188.         edge = makeLine(triangle.B, triangle.C, false, true);
  189.         edge.changeColor("", Color.PINK, null, null);
  190.         textAndStep("Edge from B to C");
  191.         boolean separatedByEdgeBC = isEdgeSA(circle, triangle, triangle.edgeBC, triangle.B, triangle.C, triangle.A);
  192.         edge.hide();
  193.        
  194.         clearText();
  195.         y = startY;
  196.        
  197.         boolean result = separatedByVertexA || separatedByVertexB || separatedByVertexC || separatedByEdgeAB || separatedByEdgeAC || separatedByEdgeBC;
  198.         if(result) {
  199.             separatingAxis.changeColor("", Color.GREEN, null, null);
  200.             separatingAxis.show();
  201.         }
  202.         textAndStep("we found separating axis = " + result);
  203.         return result;
  204.     }
  205.    
  206.    
  207.     /**
  208.      *
  209.      * @param circle
  210.      * @param triangle
  211.      * @param vertex
  212.      * @return
  213.      */
  214.     private boolean isVertexSA(auxiliary.Circle circle, auxiliary.Triangle triangle, Vector2f vertex) {
  215.         line = makeLine(circle.center.x, circle.center.y, circle.center.x + circle.radius, circle.center.y, false, true);
  216.         textAndStep("radius = " + circle.radius);
  217.         line.hide();
  218.        
  219.         sc.highlight(1);
  220.         float distToCenter = vertex.dist(circle.center);
  221.         line = makeLine(vertex, circle.center, false, true);
  222.         textAndStep("distance to center = " + distToCenter);
  223.         line.hide();
  224.         sc.unhighlight(1);
  225.        
  226.        
  227.         sc.highlight(2);
  228.         Vector2f vertexToCenter = circle.center.sub(vertex);
  229.         vectors[0] = makeLine(vertex, circle.center, true, true);
  230.         textAndStep("vector from vertex to center = " + vertexToCenter);
  231.         sc.unhighlight(2);
  232.        
  233.         Vector2f vertexToNeighbor1;
  234.         Vector2f vertexToNeighbor2;
  235.        
  236.         if(vertex == triangle.A) {
  237.             sc.highlight(6);
  238.             sc.highlight(7);
  239.             sc.highlight(9);
  240.             vertexToNeighbor1 = triangle.B.sub(vertex); // AB
  241.             vertexToNeighbor2 = triangle.C.sub(vertex); // AC
  242.             neighbor1Name = "B";
  243.             neighbor2Name = "C";
  244.             vectors[1] = makeLine(vertex, triangle.B, true, true);
  245.             textAndStep("vector from " + vertexName + " to " + neighbor1Name + " = " + vertexToNeighbor1);
  246.             sc.unhighlight(7);
  247.            
  248.             sc.highlight(8);
  249.             vectors[2] = makeLine(vertex, triangle.C, true, true);
  250.             textAndStep("vector from " + vertexName + " to " + neighbor2Name + " = " + vertexToNeighbor2);
  251.             sc.unhighlight(6);
  252.             sc.unhighlight(8);
  253.             sc.unhighlight(9);
  254.         }
  255.         else if(vertex == triangle.B) {
  256.             sc.highlight(10);
  257.             sc.highlight(11);
  258.             sc.highlight(13);
  259.             vertexToNeighbor1 = triangle.A.sub(vertex); // BA
  260.             vertexToNeighbor2 = triangle.C.sub(vertex); // BC
  261.             neighbor1Name = "A";
  262.             neighbor2Name = "C";
  263.             vectors[1] = makeLine(vertex, triangle.A, true, true);
  264.             textAndStep("vector from " + vertexName + " to " + neighbor1Name + " = " + vertexToNeighbor1);
  265.             sc.unhighlight(11);
  266.            
  267.             sc.highlight(12);
  268.             vectors[2] = makeLine(vertex, triangle.C, true, true);
  269.             textAndStep("vector from " + vertexName + " to " + neighbor2Name + " = " + vertexToNeighbor2);
  270.             sc.unhighlight(10);
  271.             sc.unhighlight(12);
  272.             sc.unhighlight(13);
  273.         }
  274.         else if(vertex == triangle.C) {
  275.             sc.highlight(14);
  276.             sc.highlight(15);
  277.             sc.highlight(17);
  278.             vertexToNeighbor1 = triangle.A.sub(vertex); // CA
  279.             vertexToNeighbor2 = triangle.B.sub(vertex); // CB
  280.             neighbor1Name = "A";
  281.             neighbor2Name = "B";
  282.             vectors[1] = makeLine(vertex, triangle.A, true, true);
  283.             textAndStep("vector from " + vertexName + " to " + neighbor1Name + " = " + vertexToNeighbor1);
  284.             sc.unhighlight(15);
  285.            
  286.             sc.highlight(16);
  287.             vectors[2] = makeLine(vertex, triangle.B, true, true);
  288.             textAndStep("vector from " + vertexName + " to " + neighbor2Name + " = " + vertexToNeighbor2);
  289.             sc.unhighlight(14);
  290.             sc.unhighlight(16);
  291.             sc.unhighlight(17);
  292.         }
  293.         else {
  294.             throw new IllegalArgumentException("The provided vertex: " + vertex + " does not match with any of the triangle's vertices.");
  295.         }
  296.        
  297. //      textAndStep("vector from " + vertexName + " to " + neighbor1Name + " = " + vertexToNeighbor1);
  298. //      textAndStep("vector from " + vertexName + " to " + neighbor2Name + " = " + vertexToNeighbor2);
  299.  
  300.         // they are on opposite sides if the dot product is less than zero
  301.         vectors[0].changeColor("", Color.LIGHT_GRAY, null, null);
  302.        
  303.         sc.highlight(21);
  304.         sc.highlight(22);
  305.         boolean isOppositeNeighbor1 = vertexToCenter.dot(vertexToNeighbor1) < 0;
  306.         vectors[1].changeColor("", Color.ORANGE, null, null);
  307.         textAndStep(neighbor1Name + " is on opposite side = " + isOppositeNeighbor1);
  308.         vectors[1].changeColor("", VECTOR_DEFAULT_COLOR, null, null);
  309.         sc.unhighlight(21);
  310.         sc.unhighlight(22);
  311.        
  312.         sc.highlight(23);
  313.         sc.highlight(24);
  314.         boolean isOppositeNeighbor2 = vertexToCenter.dot(vertexToNeighbor2) < 0;
  315.         vectors[2].changeColor("", Color.ORANGE, null, null);
  316.         textAndStep(neighbor2Name + " is on opposite side = " + isOppositeNeighbor2);
  317.         sc.unhighlight(23);
  318.         sc.unhighlight(24);
  319.        
  320.         vectors[0].hide();
  321.         vectors[1].hide();
  322.         vectors[2].hide();
  323.        
  324.         sc.highlight(26);
  325.         boolean radius_less_than_dist = circle.radius < distToCenter;
  326.         textAndStep("radius smaller than distance = " + radius_less_than_dist);
  327.        
  328.         boolean result = radius_less_than_dist && isOppositeNeighbor1 && isOppositeNeighbor2;
  329.         line = makeLine(vertex, circle.center, false, true);
  330.         line.changeColor("", result ? Color.GREEN : Color.RED, null, null);
  331.         if(result) {
  332.             separatingAxis =  makeLine(vertex, circle.center, false, true);
  333.         }
  334.         sc.highlight(27);
  335.         textAndStep("vertex is separating axis = " + result);
  336.         line.hide();
  337.         sc.unhighlight(26);
  338.         sc.unhighlight(27);
  339.         if(separatingAxis != null) {
  340.             separatingAxis.hide(); 
  341.         }
  342.         return result;
  343.     }
  344.    
  345.    
  346.     /**
  347.      *
  348.      * @param circle
  349.      * @param triangle
  350.      * @param edge
  351.      * @param start
  352.      * @param end
  353.      * @param other
  354.      * @return
  355.      */
  356.     private boolean isEdgeSA(auxiliary.Circle circle, auxiliary.Triangle triangle, Vector2f edge, Vector2f start, Vector2f end, Vector2f other) {
  357.         line = makeLine(circle.center.x, circle.center.y, circle.center.x + circle.radius, circle.center.y, false, true);
  358.         textAndStep("radius = " + circle.radius);
  359.         line.hide();
  360.        
  361.         Vector2f normalizedEdge = edge.normalize();
  362.         vector = makeLine(start.x, start.y, start.x + normalizedEdge.x, start.y + normalizedEdge.y, true, true);    // TODO: too small, does not show arrow in Animal !
  363.         vector.changeColor("", VECTOR_DEFAULT_COLOR, null, null);
  364.         textAndStep("normalized edge = " + normalizedEdge);
  365.         vector.hide();
  366.        
  367.         Vector2f vecToCircle;
  368.         if(edge == triangle.edgeAB) {
  369.             vecToCircle = circle.center.sub(triangle.A);
  370.             vector = makeLine(triangle.A, circle.center, true, true);
  371.         }
  372.         else if(edge == triangle.edgeAC) {
  373.             // TODO: why not C, or: when A, when C ?
  374.             vecToCircle = circle.center.sub(triangle.A);
  375.             vector = makeLine(triangle.A, circle.center, true, true);
  376.         }
  377.         else if(edge == triangle.edgeBC) {
  378.             vecToCircle = circle.center.sub(triangle.B);
  379.             vector = makeLine(triangle.B, circle.center, true, true);
  380.         }
  381.         else {
  382.             throw new IllegalArgumentException("The provided edge: " + edge + " does not match with any of the triangle's edges.");
  383.         }
  384.        
  385.         textAndStep("vector to circle = " + vecToCircle);
  386.         vector.hide();
  387.        
  388.         float dot = normalizedEdge.dot(vecToCircle);
  389.         line = makeLine(start.x, start.y, start.x + dot, start.y + dot, false, true);
  390.         textAndStep("dot product of normalizedEdge and vectorToCircle = " + dot);
  391.         line.hide();
  392.        
  393.         Vector2f closestPointToCircle;
  394.         if(dot <= 0) {
  395.             closestPointToCircle = start;
  396.         }
  397.         else if(dot >= edge.length()) {
  398.             closestPointToCircle = end;
  399.         }
  400.         else {
  401.             closestPointToCircle = normalizedEdge.mul(dot).add(start);
  402.         }
  403.        
  404.         Circle pointToHighlight;
  405.         boolean isFilled = true;
  406.        
  407.         line = makeLine(start, closestPointToCircle, false, true);
  408.         pointToHighlight = makeCircle(closestPointToCircle.x, closestPointToCircle.y, 0.1f, Color.PINK, isFilled);
  409.         textAndStep("closest point to circle = " + closestPointToCircle);
  410.         pointToHighlight.hide();
  411.         line.hide();
  412.        
  413.         // check if the other vertex (the one that is not part of the current edge) and the circle-center lie on opposite sides of the edge
  414.         Vector2f vecFromClosestPointToCircle        = circle.center.sub(closestPointToCircle);
  415.         vectors[0] = makeLine(closestPointToCircle, circle.center, true, true);
  416.         textAndStep("vector from closest point to circle = " + vecFromClosestPointToCircle);
  417.        
  418.         Vector2f vecFromClosestPointToOtherVertex   = other.sub(closestPointToCircle);
  419.         vectors[1] = makeLine(closestPointToCircle, other, true, true);
  420.         textAndStep("vector from closest point to other vertex = " + vecFromClosestPointToOtherVertex);
  421.        
  422.         boolean isOppositeOtherVertex               = vecFromClosestPointToCircle.dot(vecFromClosestPointToOtherVertex) < 0;
  423.         vectors[0].changeColor("", Color.BLUE, null, null);
  424.         vectors[1].changeColor("", Color.BLUE, null, null);
  425.         textAndStep("other vertex on opposite side of circle = " + isOppositeOtherVertex);
  426.        
  427.         vectors[0].hide();
  428.         vectors[1].hide();
  429.        
  430.         boolean radius_less_than_dist_to_closest_point = circle.radius < vecFromClosestPointToCircle.length();
  431.         textAndStep("radius less than distance to closest point = " + radius_less_than_dist_to_closest_point);
  432.        
  433.         boolean result = radius_less_than_dist_to_closest_point && isOppositeOtherVertex;
  434.         line = makeLine(closestPointToCircle, circle.center, false, true);
  435.         line.changeColor("", result ? Color.GREEN : Color.RED, null, null);
  436.         if(result) {
  437.             separatingAxis = makeLine(closestPointToCircle, circle.center, false, true);
  438.         }
  439.         textAndStep("is separating axis = " + result);
  440.         line.hide();
  441.         if(separatingAxis != null) {
  442.             separatingAxis.hide(); 
  443.         }
  444.         return result;
  445.     }
  446.    
  447.    
  448.     // ====================================================================================================================================
  449.     // ====================================================================================================================================
  450.    
  451.     private Circle makeCircle(float x, float y, float radius) {
  452.         return new Circle(new AnimalCircleGenerator(lang), transformCoords(x, y), transformRadius(radius), "circle", null, circleProps);
  453.     }
  454.    
  455.     private Circle makeCircle(float x, float y, float radius, Color color, boolean isFilled) {
  456.         CircleProperties props = new CircleProperties();
  457.         props.set(AnimationPropertiesKeys.FILL_PROPERTY, color);
  458.         props.set(AnimationPropertiesKeys.FILLED_PROPERTY, isFilled);
  459.         return new Circle(new AnimalCircleGenerator(lang), transformCoords(x, y), transformRadius(radius), "circle", null, props);
  460.     }
  461.    
  462.     private Triangle makeTriangle(Vector2f A, Vector2f B, Vector2f C) {
  463.         return makeTriangle(A.x, A.y, B.x, B.y, C.x, C.y);
  464.     }
  465.    
  466.     private Triangle makeTriangle(float Ax, float Ay, float Bx, float By, float Cx, float Cy) {
  467.         return new Triangle(new AnimalTriangleGenerator(lang),
  468.                 transformCoords(Ax, Ay),
  469.                 transformCoords(Bx, By),
  470.                 transformCoords(Cx, Cy),
  471.                 "triangle",
  472.                 null,
  473.                 triangleProps);
  474.     }
  475.    
  476.     private Coordinates transformCoords(float x, float y) {
  477.         float newX = 600 + 40 * x;
  478.         float newY = 300 - 40 * y;
  479.         return new Coordinates((int)newX, (int)newY);
  480.     }
  481.    
  482.     private int transformRadius(float radius) {
  483.         float newRadius = 40 * radius;
  484.         return (int)newRadius;
  485.     }
  486.    
  487.     private Rect makeRect(int upperLeftX, int upperLeftY, int lowerRightX, int lowerRightY) {
  488.         return new Rect(new AnimalRectGenerator(lang), new Coordinates(upperLeftX, upperLeftY), new Coordinates(lowerRightX, lowerRightY), "rect", null, rectProps);
  489.     }
  490.    
  491.     private Text makeText(String text, int x, int y) {
  492.         return new Text(new AnimalTextGenerator(lang), new Coordinates(x, y), text, "text", null, textProps);
  493.     }
  494.    
  495.     private void textAndStep(String text) {
  496.         textAndStep(text, this.x, this.y);
  497.     }
  498.    
  499.     private void textAndStep(String text, int x, int y) {
  500.         textList.add(makeText(text, x, y));
  501.         this.y += offsetY;
  502.         lang.nextStep();
  503.     }
  504.    
  505.     private void clearText() {
  506.         for(Text text : textList) {
  507.             text.setText("", null, null);
  508.         }
  509.        
  510.         textList = new ArrayList<>();
  511.     }
  512.    
  513.    
  514.     private Polyline makeLine(Vector2f from, Vector2f to, boolean isVector, boolean needsTransform) {
  515.         return makeLine(from.x, from.y, to.x, to.y, isVector, needsTransform);
  516.     }
  517.    
  518.     private Polyline makeLine(float startX, float startY, float endX, float endY, boolean isVector, boolean needsTransform) {
  519.         Node[] nodeArray;
  520.         if(needsTransform) {
  521.             nodeArray = new Node[] {
  522.                     transformCoords(startX, startY),
  523.                     transformCoords(endX, endY)
  524.             };
  525.         }
  526.         else {
  527.             nodeArray = new Node[] {
  528.                     new Coordinates((int)startX, (int)startY),
  529.                     new Coordinates((int)endX, (int)endY)
  530.             };
  531.         }
  532.        
  533.         return new Polyline(new AnimalPolylineGenerator(lang), nodeArray, "line", null, isVector ? vectorProps : lineProps);
  534.     }
  535.    
  536.     private void makeHeader() {
  537.         makeRect(430, 25, 790, 50);
  538.        
  539.         TextProperties titleProps = new TextProperties();
  540.         titleProps.set(AnimationPropertiesKeys.FONT_PROPERTY, new Font("Arial", Font.BOLD, 16));
  541.         new Text(new AnimalTextGenerator(lang), new Coordinates(450, 27), "Separating Axis Theorem (Circle-Triangle)", "title", null, titleProps);
  542.     }
  543.    
  544.     private void makeSideBox() {
  545.         makeRect(900, 150, 1300, 380);
  546.     }
  547.    
  548.     private void drawCoordSystem() {
  549.         int xAxis       = 300;
  550.         int xAxisStart  = 400;
  551.         int xAxisEnd    = 800;
  552.        
  553.         int yAxis       = 600;
  554.         int yAxisStart  = 500;
  555.         int yAxisEnd    = 100;
  556.        
  557.         makeLine(xAxisStart, xAxis, xAxisEnd, xAxis, false, false); // x-axis (600px)
  558.         makeLine(yAxis, yAxisStart, yAxis, yAxisEnd, false, false); // y-axis (400px)
  559.        
  560.         int offset = 40;    // 60px = 1cm
  561.        
  562.         // x-axis
  563.         for(int i=xAxisStart; i <= xAxisEnd; i+=offset) {
  564.             makeLine(i, xAxis-5, i, xAxis+5, false, false);
  565.         }
  566.        
  567.         // y-axis
  568.         for(int i=yAxisStart; i >= yAxisEnd; i-=offset) {
  569.             makeLine(yAxis-5, i, yAxis+5, i, false, false);
  570.         }
  571.     }
  572.    
  573.     // ====================================================================================================================================
  574.     // ====================================================================================================================================
  575.     // ====================================================================================================================================
  576.     // ====================================================================================================================================
  577.     // ====================================================================================================================================
  578.     // ====================================================================================================================================
  579.    
  580.     public static void main(String[] args) {
  581.         // careful: animalscript y-coord goes downwards (i.e. 110 is below 100)
  582.         SAT sat = new SAT();
  583.         sat.init();
  584.        
  585.         auxiliary.Circle C = new auxiliary.Circle(new Vector2f(-2, 1), 2);
  586.         auxiliary.Triangle T = new auxiliary.Triangle(new Vector2f(1, 1), new Vector2f(3, 1), new Vector2f(2, 4));
  587.         sat.hasSA(C, T);
  588.        
  589.         System.out.println(sat.lang);
  590.     }
  591.    
  592.    
  593.     public void showSourceCodeVertexSA() {
  594.         // first set the visual properties for the source code
  595.         SourceCodeProperties scProps = new SourceCodeProperties();
  596.         scProps.set(AnimationPropertiesKeys.CONTEXTCOLOR_PROPERTY, Color.BLUE);
  597.         scProps.set(AnimationPropertiesKeys.FONT_PROPERTY, new Font("Monospaced", Font.PLAIN, 12));
  598.         scProps.set(AnimationPropertiesKeys.HIGHLIGHTCOLOR_PROPERTY, Color.RED);
  599.         scProps.set(AnimationPropertiesKeys.COLOR_PROPERTY, Color.BLACK);
  600.        
  601.         // now create the source code entity
  602.         sc = lang.newSourceCode(new Coordinates(10, 50), "sourceCode", null, scProps);
  603.        
  604.         // add code lines (the actual sorting algo)
  605.         // parameters: code itself, name (can be null), indention level, display options
  606.         sc.addCodeLine("boolean isVertexSA(Circle circle, Triangle triangle, Vector2f vertex) {", null, 0, null);
  607.         sc.addCodeLine("float distToCenter = vertex.dist(circle.center);", null, 1, null);
  608.         sc.addCodeLine("Vector2f vertexToCenter = circle.center.sub(vertex);", null, 1, null);
  609.         sc.addCodeLine("Vector2f vertexToNeighbor1;", null, 1, null);
  610.         sc.addCodeLine("Vector2f vertexToNeighbor2;", null, 1, null);
  611.         sc.addCodeLine("", null, 0, null);
  612.         sc.addCodeLine("if(vertex == triangle.A) {", null, 1, null);
  613.         sc.addCodeLine("vertexToNeighbor1 = triangle.B.sub(vertex); // AB", null, 2, null);
  614.         sc.addCodeLine("vertexToNeighbor2 = triangle.C.sub(vertex); // AC", null, 2, null);
  615.         sc.addCodeLine("}", null, 1, null);
  616.         sc.addCodeLine("else if(vertex == triangle.B) {", null, 1, null);
  617.         sc.addCodeLine("vertexToNeighbor1 = triangle.A.sub(vertex); // BA", null, 2, null);
  618.         sc.addCodeLine("vertexToNeighbor2 = triangle.C.sub(vertex); // BC", null, 2, null);
  619.         sc.addCodeLine("}", null, 1, null);
  620.         sc.addCodeLine("else if(vertex == triangle.C) {", null, 1, null);
  621.         sc.addCodeLine("vertexToNeighbor1 = triangle.A.sub(vertex); // CA", null, 2, null);
  622.         sc.addCodeLine("vertexToNeighbor2 = triangle.B.sub(vertex); // CB", null, 2, null);
  623.         sc.addCodeLine("}", null, 1, null);
  624.         sc.addCodeLine("", null, 0, null);
  625.         sc.addCodeLine("// they are on opposite sides", null, 1, null);
  626.         sc.addCodeLine("// if the dot product is less than zero", null, 1, null);
  627.         sc.addCodeLine("boolean isOppositeNeighbor1 = ", null, 1, null);
  628.         sc.addCodeLine("vertexToCenter.dot(vertexToNeighbor1) < 0;", null, 2, null);
  629.         sc.addCodeLine("boolean isOppositeNeighbor2 = ", null, 1, null);
  630.         sc.addCodeLine("vertexToCenter.dot(vertexToNeighbor2) < 0;", null, 2, null);
  631.         sc.addCodeLine("", null, 0, null);
  632.         sc.addCodeLine("return circle.radius < distToCenter", null, 1, null);
  633.         sc.addCodeLine("&& isOppositeNeighbor1 && isOppositeNeighbor2;", null, 2, null);
  634.     } // showSourceCodeVertexSA()
  635.    
  636.    
  637.     public void showSourceCodeEdgeSA() {
  638.         // first set the visual properties for the source code
  639.         SourceCodeProperties scProps = new SourceCodeProperties();
  640.         scProps.set(AnimationPropertiesKeys.CONTEXTCOLOR_PROPERTY, Color.BLUE);
  641.         scProps.set(AnimationPropertiesKeys.FONT_PROPERTY, new Font("Monospaced", Font.PLAIN, 12));
  642.         scProps.set(AnimationPropertiesKeys.HIGHLIGHTCOLOR_PROPERTY, Color.RED);
  643.         scProps.set(AnimationPropertiesKeys.COLOR_PROPERTY, Color.BLACK);
  644.        
  645.         // now create the source code entity
  646.         sc = lang.newSourceCode(new Coordinates(10, 50), "sourceCode", null, scProps);
  647.        
  648.         // add code lines (the actual sorting algo)
  649.         // parameters: code itself, name (can be null), indention level, display options
  650.         sc.addCodeLine("boolean isEdgeSA(Circle circle, Triangle triangle, Vector2f edge, Vector2f start, Vector2f end, Vector2f other) {", null, 0, null);
  651.         sc.addCodeLine("Vector2f normalizedEdge = edge.normalize();", null, 1, null);
  652.         sc.addCodeLine("Vector2f vecToCircle;", null, 1, null);
  653.         sc.addCodeLine("", null, 0, null);
  654.         sc.addCodeLine("if(edge == triangle.edgeAB) {", null, 1, null);
  655.         sc.addCodeLine("vecToCircle = circle.center.sub(triangle.A);", null, 2, null);
  656.         sc.addCodeLine("}", null, 1, null);
  657.         sc.addCodeLine("else if(edge == triangle.edgeAC) {", null, 1, null);
  658.         sc.addCodeLine("vecToCircle = circle.center.sub(triangle.A);", null, 2, null);
  659.         sc.addCodeLine("}", null, 1, null);
  660.         sc.addCodeLine("else if(edge == triangle.edgeBC) {", null, 1, null);
  661.         sc.addCodeLine("vecToCircle = circle.center.sub(triangle.B);", null, 2, null);
  662.         sc.addCodeLine("}", null, 1, null);
  663.         sc.addCodeLine("float dot = normalizedEdge.dot(vecToCircle);", null, 1, null);
  664.         sc.addCodeLine("Vector2f closestPointToCircle;", null, 1, null);
  665.         sc.addCodeLine("if(dot <= 0) {", null, 1, null);
  666.         sc.addCodeLine("closestPointToCircle = start;", null, 2, null);
  667.         sc.addCodeLine("}", null, 1, null);
  668.         sc.addCodeLine("else if(dot >= edge.length()) {", null, 1, null);
  669.         sc.addCodeLine("closestPointToCircle = end;", null, 2, null);
  670.         sc.addCodeLine("}", null, 1, null);
  671.         sc.addCodeLine("else {", null, 1, null);
  672.         sc.addCodeLine("closestPointToCircle = ", null, 2, null);
  673.         sc.addCodeLine("normalizedEdge.mul(dot).add(start);", null, 3, null);
  674.         sc.addCodeLine("}", null, 1, null);
  675.         sc.addCodeLine("", null, 0, null);
  676.         sc.addCodeLine("// check if the other vertex", null, 1, null);
  677.         sc.addCodeLine("// (the one that is not part of the current edge)", null, 1, null);
  678.         sc.addCodeLine("// and the circle-center lie on opposite sides of the edge", null, 1, null);
  679.         sc.addCodeLine("Vector2f vecFromClosestPointToCircle        = ", null, 1, null);
  680.         sc.addCodeLine("circle.center.sub(closestPointToCircle);", null, 2, null);
  681.         sc.addCodeLine("Vector2f vecFromClosestPointToOtherVertex   = ", null, 1, null);
  682.         sc.addCodeLine("other.sub(closestPointToCircle); ", null, 2, null);
  683.         sc.addCodeLine("boolean isOppositeOtherVertex               = vecFromClosestPointToCircle.dot(vecFromClosestPointToOtherVertex) < 0;", null, 1, null);
  684.         sc.addCodeLine("", null, 0, null);
  685.         sc.addCodeLine("return circle.radius < vecFromClosestPointToCircle.length() && isOppositeOtherVertex;", null, 1, null);
  686.     } // showSourceCodeEdgeSA()
  687. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement