Advertisement
bekovski

algovi_sat

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