Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.awt.Color;
- import java.awt.Font;
- import java.util.ArrayList;
- import java.util.List;
- import algoanim.animalscript.AnimalCircleGenerator;
- import algoanim.animalscript.AnimalPointGenerator;
- import algoanim.animalscript.AnimalPolylineGenerator;
- import algoanim.animalscript.AnimalRectGenerator;
- import algoanim.animalscript.AnimalScript;
- import algoanim.animalscript.AnimalTextGenerator;
- import algoanim.animalscript.AnimalTriangleGenerator;
- import algoanim.primitives.Circle;
- import algoanim.primitives.Point;
- import algoanim.primitives.Polyline;
- import algoanim.primitives.Rect;
- import algoanim.primitives.SourceCode;
- import algoanim.primitives.Text;
- import algoanim.primitives.Triangle;
- import algoanim.primitives.generators.Language;
- import algoanim.properties.AnimationPropertiesKeys;
- import algoanim.properties.CircleProperties;
- import algoanim.properties.PointProperties;
- import algoanim.properties.PolylineProperties;
- import algoanim.properties.RectProperties;
- import algoanim.properties.SourceCodeProperties;
- import algoanim.properties.TextProperties;
- import algoanim.properties.TriangleProperties;
- import algoanim.util.Coordinates;
- import algoanim.util.Node;
- import algoanim.util.TicksTiming;
- import algoanim.util.Timing;
- import auxiliary.Vector2f;
- public class SAT {
- public static final Color LINE_DEFAULT_COLOR = Color.BLACK;
- public static final Color VECTOR_DEFAULT_COLOR = Color.RED;
- Language lang;
- Text text;
- Point point;
- Circle circle;
- Polyline line;
- Polyline edge;
- Polyline vector;
- Polyline separatingAxis;
- Triangle triangle;
- // temp
- Polyline[] vectors = new Polyline[3];
- SourceCode sc;
- Timing timing;
- // might need these properties
- TextProperties textProps;
- RectProperties rectProps;
- PointProperties pointProps;
- CircleProperties circleProps;
- PolylineProperties lineProps;
- PolylineProperties vectorProps;
- TriangleProperties triangleProps;
- int x = 40;
- int y = 140;
- int startY;
- int offsetY = 20;
- String vertexName;
- String neighbor1Name;
- String neighbor2Name;
- List<Text> textList = new ArrayList<>();
- public void init() {
- lang = new AnimalScript("Separating Axis Theorem (Circle-Triangle)", "Bekir Oezkara", 640, 480);
- lang.setStepMode(true);
- timing = new TicksTiming(200);
- textProps = new TextProperties();
- textProps.set(AnimationPropertiesKeys.COLOR_PROPERTY, Color.BLACK);
- textProps.set(AnimationPropertiesKeys.FONT_PROPERTY, new Font("Monospaced", Font.PLAIN, 12));
- rectProps = new RectProperties();
- rectProps.set(AnimationPropertiesKeys.COLOR_PROPERTY, Color.DARK_GRAY);
- rectProps.set(AnimationPropertiesKeys.FILLED_PROPERTY, true);
- rectProps.set(AnimationPropertiesKeys.FILL_PROPERTY, Color.LIGHT_GRAY);
- rectProps.set(AnimationPropertiesKeys.DEPTH_PROPERTY, 2);
- pointProps = new PointProperties();
- pointProps.set(AnimationPropertiesKeys.COLOR_PROPERTY, Color.CYAN);
- circleProps = new CircleProperties();
- // circleProps.set(AnimationPropertiesKeys.COLOR_PROPERTY, Color.RED);
- circleProps.set(AnimationPropertiesKeys.FILL_PROPERTY, Color.WHITE);
- lineProps = new PolylineProperties();
- lineProps.set(AnimationPropertiesKeys.COLOR_PROPERTY, LINE_DEFAULT_COLOR);
- vectorProps = new PolylineProperties();
- vectorProps.set(AnimationPropertiesKeys.COLOR_PROPERTY, VECTOR_DEFAULT_COLOR);
- vectorProps.set(AnimationPropertiesKeys.FWARROW_PROPERTY, true);
- triangleProps = new TriangleProperties();
- // triangleProps.set(AnimationPropertiesKeys.COLOR_PROPERTY, Color.GREEN);
- triangleProps.set(AnimationPropertiesKeys.FILL_PROPERTY, Color.WHITE);
- makeHeader();
- makeSideBox();
- drawCoordSystem();
- }
- public boolean hasSA(auxiliary.Circle circle, auxiliary.Triangle triangle) {
- makeCircle(circle.center.x, circle.center.y, circle.radius);
- makeTriangle(triangle.A, triangle.B, triangle.C);
- lang.nextStep();
- x = 910;
- startY = 160;
- y = startY;
- // vertices
- showSourceCodeVertexSA();
- Circle vertexHighlightCircle;
- boolean isFilled = true;
- vertexName = "A";
- neighbor1Name = "B";
- neighbor2Name = "C";
- vertexHighlightCircle = makeCircle(triangle.A.x, triangle.A.y, 0.1f, Color.PINK, isFilled);
- textAndStep("Vertex A");
- vertexHighlightCircle.hide();
- boolean separatedByVertexA = isVertexSA(circle, triangle, triangle.A);
- clearText();
- y = startY;
- vertexName = "B";
- neighbor1Name = "A";
- neighbor2Name = "C";
- vertexHighlightCircle = makeCircle(triangle.B.x, triangle.B.y, 0.1f, Color.PINK, isFilled);
- textAndStep("Vertex B");
- vertexHighlightCircle.hide();
- boolean separatedByVertexB = isVertexSA(circle, triangle, triangle.B);
- clearText();
- y = startY;
- vertexName = "C";
- neighbor1Name = "A";
- neighbor2Name = "B";
- vertexHighlightCircle = makeCircle(triangle.C.x, triangle.C.y, 0.1f, Color.PINK, isFilled);
- textAndStep("Vertex C");
- vertexHighlightCircle.hide();
- boolean separatedByVertexC = isVertexSA(circle, triangle, triangle.C);
- clearText();
- y = startY;
- // edges
- // sc.changeColor("", Color.WHITE, null, null);
- // showSourceCodeEdgeSA();
- edge = makeLine(triangle.A, triangle.B, false, true);
- edge.changeColor("", Color.PINK, null, null);
- textAndStep("Edge from A to B");
- boolean separatedByEdgeAB = isEdgeSA(circle, triangle, triangle.edgeAB, triangle.A, triangle.B, triangle.C);
- edge.hide();
- clearText();
- y = startY;
- edge = makeLine(triangle.A, triangle.C, false, true);
- edge.changeColor("", Color.PINK, null, null);
- textAndStep("Edge from A to C");
- boolean separatedByEdgeAC = isEdgeSA(circle, triangle, triangle.edgeAC, triangle.A, triangle.C, triangle.B);
- edge.changeColor("", Color.BLACK, null, null);
- clearText();
- y = startY;
- edge = makeLine(triangle.B, triangle.C, false, true);
- edge.changeColor("", Color.PINK, null, null);
- textAndStep("Edge from B to C");
- boolean separatedByEdgeBC = isEdgeSA(circle, triangle, triangle.edgeBC, triangle.B, triangle.C, triangle.A);
- edge.hide();
- clearText();
- y = startY;
- boolean result = separatedByVertexA || separatedByVertexB || separatedByVertexC || separatedByEdgeAB || separatedByEdgeAC || separatedByEdgeBC;
- if(result) {
- separatingAxis.changeColor("", Color.GREEN, null, null);
- separatingAxis.show();
- }
- textAndStep("we found separating axis = " + result);
- return result;
- }
- /**
- *
- * @param circle
- * @param triangle
- * @param vertex
- * @return
- */
- private boolean isVertexSA(auxiliary.Circle circle, auxiliary.Triangle triangle, Vector2f vertex) {
- line = makeLine(circle.center.x, circle.center.y, circle.center.x + circle.radius, circle.center.y, false, true);
- textAndStep("radius = " + circle.radius);
- line.hide();
- sc.highlight(1);
- float distToCenter = vertex.dist(circle.center);
- line = makeLine(vertex, circle.center, false, true);
- textAndStep("distance to center = " + distToCenter);
- line.hide();
- sc.unhighlight(1);
- sc.highlight(2);
- Vector2f vertexToCenter = circle.center.sub(vertex);
- vectors[0] = makeLine(vertex, circle.center, true, true);
- textAndStep("vector from vertex to center = " + vertexToCenter);
- sc.unhighlight(2);
- Vector2f vertexToNeighbor1;
- Vector2f vertexToNeighbor2;
- if(vertex == triangle.A) {
- sc.highlight(6);
- sc.highlight(7);
- sc.highlight(9);
- vertexToNeighbor1 = triangle.B.sub(vertex); // AB
- vertexToNeighbor2 = triangle.C.sub(vertex); // AC
- neighbor1Name = "B";
- neighbor2Name = "C";
- vectors[1] = makeLine(vertex, triangle.B, true, true);
- textAndStep("vector from " + vertexName + " to " + neighbor1Name + " = " + vertexToNeighbor1);
- sc.unhighlight(7);
- sc.highlight(8);
- vectors[2] = makeLine(vertex, triangle.C, true, true);
- textAndStep("vector from " + vertexName + " to " + neighbor2Name + " = " + vertexToNeighbor2);
- sc.unhighlight(6);
- sc.unhighlight(8);
- sc.unhighlight(9);
- }
- else if(vertex == triangle.B) {
- sc.highlight(10);
- sc.highlight(11);
- sc.highlight(13);
- vertexToNeighbor1 = triangle.A.sub(vertex); // BA
- vertexToNeighbor2 = triangle.C.sub(vertex); // BC
- neighbor1Name = "A";
- neighbor2Name = "C";
- vectors[1] = makeLine(vertex, triangle.A, true, true);
- textAndStep("vector from " + vertexName + " to " + neighbor1Name + " = " + vertexToNeighbor1);
- sc.unhighlight(11);
- sc.highlight(12);
- vectors[2] = makeLine(vertex, triangle.C, true, true);
- textAndStep("vector from " + vertexName + " to " + neighbor2Name + " = " + vertexToNeighbor2);
- sc.unhighlight(10);
- sc.unhighlight(12);
- sc.unhighlight(13);
- }
- else if(vertex == triangle.C) {
- sc.highlight(14);
- sc.highlight(15);
- sc.highlight(17);
- vertexToNeighbor1 = triangle.A.sub(vertex); // CA
- vertexToNeighbor2 = triangle.B.sub(vertex); // CB
- neighbor1Name = "A";
- neighbor2Name = "B";
- vectors[1] = makeLine(vertex, triangle.A, true, true);
- textAndStep("vector from " + vertexName + " to " + neighbor1Name + " = " + vertexToNeighbor1);
- sc.unhighlight(15);
- sc.highlight(16);
- vectors[2] = makeLine(vertex, triangle.B, true, true);
- textAndStep("vector from " + vertexName + " to " + neighbor2Name + " = " + vertexToNeighbor2);
- sc.unhighlight(14);
- sc.unhighlight(16);
- sc.unhighlight(17);
- }
- else {
- throw new IllegalArgumentException("The provided vertex: " + vertex + " does not match with any of the triangle's vertices.");
- }
- // textAndStep("vector from " + vertexName + " to " + neighbor1Name + " = " + vertexToNeighbor1);
- // textAndStep("vector from " + vertexName + " to " + neighbor2Name + " = " + vertexToNeighbor2);
- // they are on opposite sides if the dot product is less than zero
- vectors[0].changeColor("", Color.LIGHT_GRAY, null, null);
- sc.highlight(21);
- sc.highlight(22);
- boolean isOppositeNeighbor1 = vertexToCenter.dot(vertexToNeighbor1) < 0;
- vectors[1].changeColor("", Color.ORANGE, null, null);
- textAndStep(neighbor1Name + " is on opposite side = " + isOppositeNeighbor1);
- vectors[1].changeColor("", VECTOR_DEFAULT_COLOR, null, null);
- sc.unhighlight(21);
- sc.unhighlight(22);
- sc.highlight(23);
- sc.highlight(24);
- boolean isOppositeNeighbor2 = vertexToCenter.dot(vertexToNeighbor2) < 0;
- vectors[2].changeColor("", Color.ORANGE, null, null);
- textAndStep(neighbor2Name + " is on opposite side = " + isOppositeNeighbor2);
- sc.unhighlight(23);
- sc.unhighlight(24);
- vectors[0].hide();
- vectors[1].hide();
- vectors[2].hide();
- sc.highlight(26);
- boolean radius_less_than_dist = circle.radius < distToCenter;
- textAndStep("radius smaller than distance = " + radius_less_than_dist);
- boolean result = radius_less_than_dist && isOppositeNeighbor1 && isOppositeNeighbor2;
- line = makeLine(vertex, circle.center, false, true);
- line.changeColor("", result ? Color.GREEN : Color.RED, null, null);
- if(result) {
- separatingAxis = makeLine(vertex, circle.center, false, true);
- }
- sc.highlight(27);
- textAndStep("vertex is separating axis = " + result);
- line.hide();
- sc.unhighlight(26);
- sc.unhighlight(27);
- if(separatingAxis != null) {
- separatingAxis.hide();
- }
- return result;
- }
- /**
- *
- * @param circle
- * @param triangle
- * @param edge
- * @param start
- * @param end
- * @param other
- * @return
- */
- private boolean isEdgeSA(auxiliary.Circle circle, auxiliary.Triangle triangle, Vector2f edge, Vector2f start, Vector2f end, Vector2f other) {
- line = makeLine(circle.center.x, circle.center.y, circle.center.x + circle.radius, circle.center.y, false, true);
- textAndStep("radius = " + circle.radius);
- line.hide();
- Vector2f normalizedEdge = edge.normalize();
- 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 !
- vector.changeColor("", VECTOR_DEFAULT_COLOR, null, null);
- textAndStep("normalized edge = " + normalizedEdge);
- vector.hide();
- Vector2f vecToCircle;
- if(edge == triangle.edgeAB) {
- vecToCircle = circle.center.sub(triangle.A);
- vector = makeLine(triangle.A, circle.center, true, true);
- }
- else if(edge == triangle.edgeAC) {
- // TODO: why not C, or: when A, when C ?
- vecToCircle = circle.center.sub(triangle.A);
- vector = makeLine(triangle.A, circle.center, true, true);
- }
- else if(edge == triangle.edgeBC) {
- vecToCircle = circle.center.sub(triangle.B);
- vector = makeLine(triangle.B, circle.center, true, true);
- }
- else {
- throw new IllegalArgumentException("The provided edge: " + edge + " does not match with any of the triangle's edges.");
- }
- textAndStep("vector to circle = " + vecToCircle);
- vector.hide();
- float dot = normalizedEdge.dot(vecToCircle);
- line = makeLine(start.x, start.y, start.x + dot, start.y + dot, false, true);
- textAndStep("dot product of normalizedEdge and vectorToCircle = " + dot);
- line.hide();
- Vector2f closestPointToCircle;
- if(dot <= 0) {
- closestPointToCircle = start;
- }
- else if(dot >= edge.length()) {
- closestPointToCircle = end;
- }
- else {
- closestPointToCircle = normalizedEdge.mul(dot).add(start);
- }
- Circle pointToHighlight;
- boolean isFilled = true;
- line = makeLine(start, closestPointToCircle, false, true);
- pointToHighlight = makeCircle(closestPointToCircle.x, closestPointToCircle.y, 0.1f, Color.PINK, isFilled);
- textAndStep("closest point to circle = " + closestPointToCircle);
- pointToHighlight.hide();
- line.hide();
- // 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
- Vector2f vecFromClosestPointToCircle = circle.center.sub(closestPointToCircle);
- vectors[0] = makeLine(closestPointToCircle, circle.center, true, true);
- textAndStep("vector from closest point to circle = " + vecFromClosestPointToCircle);
- Vector2f vecFromClosestPointToOtherVertex = other.sub(closestPointToCircle);
- vectors[1] = makeLine(closestPointToCircle, other, true, true);
- textAndStep("vector from closest point to other vertex = " + vecFromClosestPointToOtherVertex);
- boolean isOppositeOtherVertex = vecFromClosestPointToCircle.dot(vecFromClosestPointToOtherVertex) < 0;
- vectors[0].changeColor("", Color.BLUE, null, null);
- vectors[1].changeColor("", Color.BLUE, null, null);
- textAndStep("other vertex on opposite side of circle = " + isOppositeOtherVertex);
- vectors[0].hide();
- vectors[1].hide();
- boolean radius_less_than_dist_to_closest_point = circle.radius < vecFromClosestPointToCircle.length();
- textAndStep("radius less than distance to closest point = " + radius_less_than_dist_to_closest_point);
- boolean result = radius_less_than_dist_to_closest_point && isOppositeOtherVertex;
- line = makeLine(closestPointToCircle, circle.center, false, true);
- line.changeColor("", result ? Color.GREEN : Color.RED, null, null);
- if(result) {
- separatingAxis = makeLine(closestPointToCircle, circle.center, false, true);
- }
- textAndStep("is separating axis = " + result);
- line.hide();
- if(separatingAxis != null) {
- separatingAxis.hide();
- }
- return result;
- }
- // ====================================================================================================================================
- // ====================================================================================================================================
- private Circle makeCircle(float x, float y, float radius) {
- return new Circle(new AnimalCircleGenerator(lang), transformCoords(x, y), transformRadius(radius), "circle", null, circleProps);
- }
- private Circle makeCircle(float x, float y, float radius, Color color, boolean isFilled) {
- CircleProperties props = new CircleProperties();
- props.set(AnimationPropertiesKeys.FILL_PROPERTY, color);
- props.set(AnimationPropertiesKeys.FILLED_PROPERTY, isFilled);
- return new Circle(new AnimalCircleGenerator(lang), transformCoords(x, y), transformRadius(radius), "circle", null, props);
- }
- private Triangle makeTriangle(Vector2f A, Vector2f B, Vector2f C) {
- return makeTriangle(A.x, A.y, B.x, B.y, C.x, C.y);
- }
- private Triangle makeTriangle(float Ax, float Ay, float Bx, float By, float Cx, float Cy) {
- return new Triangle(new AnimalTriangleGenerator(lang),
- transformCoords(Ax, Ay),
- transformCoords(Bx, By),
- transformCoords(Cx, Cy),
- "triangle",
- null,
- triangleProps);
- }
- private Coordinates transformCoords(float x, float y) {
- float newX = 600 + 40 * x;
- float newY = 300 - 40 * y;
- return new Coordinates((int)newX, (int)newY);
- }
- private int transformRadius(float radius) {
- float newRadius = 40 * radius;
- return (int)newRadius;
- }
- private Rect makeRect(int upperLeftX, int upperLeftY, int lowerRightX, int lowerRightY) {
- return new Rect(new AnimalRectGenerator(lang), new Coordinates(upperLeftX, upperLeftY), new Coordinates(lowerRightX, lowerRightY), "rect", null, rectProps);
- }
- private Text makeText(String text, int x, int y) {
- return new Text(new AnimalTextGenerator(lang), new Coordinates(x, y), text, "text", null, textProps);
- }
- private void textAndStep(String text) {
- textAndStep(text, this.x, this.y);
- }
- private void textAndStep(String text, int x, int y) {
- textList.add(makeText(text, x, y));
- this.y += offsetY;
- lang.nextStep();
- }
- private void clearText() {
- for(Text text : textList) {
- text.setText("", null, null);
- }
- textList = new ArrayList<>();
- }
- private Polyline makeLine(Vector2f from, Vector2f to, boolean isVector, boolean needsTransform) {
- return makeLine(from.x, from.y, to.x, to.y, isVector, needsTransform);
- }
- private Polyline makeLine(float startX, float startY, float endX, float endY, boolean isVector, boolean needsTransform) {
- Node[] nodeArray;
- if(needsTransform) {
- nodeArray = new Node[] {
- transformCoords(startX, startY),
- transformCoords(endX, endY)
- };
- }
- else {
- nodeArray = new Node[] {
- new Coordinates((int)startX, (int)startY),
- new Coordinates((int)endX, (int)endY)
- };
- }
- return new Polyline(new AnimalPolylineGenerator(lang), nodeArray, "line", null, isVector ? vectorProps : lineProps);
- }
- private void makeHeader() {
- makeRect(430, 25, 790, 50);
- TextProperties titleProps = new TextProperties();
- titleProps.set(AnimationPropertiesKeys.FONT_PROPERTY, new Font("Arial", Font.BOLD, 16));
- new Text(new AnimalTextGenerator(lang), new Coordinates(450, 27), "Separating Axis Theorem (Circle-Triangle)", "title", null, titleProps);
- }
- private void makeSideBox() {
- makeRect(900, 150, 1300, 380);
- }
- private void drawCoordSystem() {
- int xAxis = 300;
- int xAxisStart = 400;
- int xAxisEnd = 800;
- int yAxis = 600;
- int yAxisStart = 500;
- int yAxisEnd = 100;
- makeLine(xAxisStart, xAxis, xAxisEnd, xAxis, false, false); // x-axis (600px)
- makeLine(yAxis, yAxisStart, yAxis, yAxisEnd, false, false); // y-axis (400px)
- int offset = 40; // 60px = 1cm
- // x-axis
- for(int i=xAxisStart; i <= xAxisEnd; i+=offset) {
- makeLine(i, xAxis-5, i, xAxis+5, false, false);
- }
- // y-axis
- for(int i=yAxisStart; i >= yAxisEnd; i-=offset) {
- makeLine(yAxis-5, i, yAxis+5, i, false, false);
- }
- }
- // ====================================================================================================================================
- // ====================================================================================================================================
- // ====================================================================================================================================
- // ====================================================================================================================================
- // ====================================================================================================================================
- // ====================================================================================================================================
- public static void main(String[] args) {
- // careful: animalscript y-coord goes downwards (i.e. 110 is below 100)
- SAT sat = new SAT();
- sat.init();
- auxiliary.Circle C = new auxiliary.Circle(new Vector2f(-2, 1), 2);
- auxiliary.Triangle T = new auxiliary.Triangle(new Vector2f(1, 1), new Vector2f(3, 1), new Vector2f(2, 4));
- sat.hasSA(C, T);
- System.out.println(sat.lang);
- }
- public void showSourceCodeVertexSA() {
- // first set the visual properties for the source code
- SourceCodeProperties scProps = new SourceCodeProperties();
- scProps.set(AnimationPropertiesKeys.CONTEXTCOLOR_PROPERTY, Color.BLUE);
- scProps.set(AnimationPropertiesKeys.FONT_PROPERTY, new Font("Monospaced", Font.PLAIN, 12));
- scProps.set(AnimationPropertiesKeys.HIGHLIGHTCOLOR_PROPERTY, Color.RED);
- scProps.set(AnimationPropertiesKeys.COLOR_PROPERTY, Color.BLACK);
- // now create the source code entity
- sc = lang.newSourceCode(new Coordinates(10, 50), "sourceCode", null, scProps);
- // add code lines (the actual sorting algo)
- // parameters: code itself, name (can be null), indention level, display options
- sc.addCodeLine("boolean isVertexSA(Circle circle, Triangle triangle, Vector2f vertex) {", null, 0, null);
- sc.addCodeLine("float distToCenter = vertex.dist(circle.center);", null, 1, null);
- sc.addCodeLine("Vector2f vertexToCenter = circle.center.sub(vertex);", null, 1, null);
- sc.addCodeLine("Vector2f vertexToNeighbor1;", null, 1, null);
- sc.addCodeLine("Vector2f vertexToNeighbor2;", null, 1, null);
- sc.addCodeLine("", null, 0, null);
- sc.addCodeLine("if(vertex == triangle.A) {", null, 1, null);
- sc.addCodeLine("vertexToNeighbor1 = triangle.B.sub(vertex); // AB", null, 2, null);
- sc.addCodeLine("vertexToNeighbor2 = triangle.C.sub(vertex); // AC", null, 2, null);
- sc.addCodeLine("}", null, 1, null);
- sc.addCodeLine("else if(vertex == triangle.B) {", null, 1, null);
- sc.addCodeLine("vertexToNeighbor1 = triangle.A.sub(vertex); // BA", null, 2, null);
- sc.addCodeLine("vertexToNeighbor2 = triangle.C.sub(vertex); // BC", null, 2, null);
- sc.addCodeLine("}", null, 1, null);
- sc.addCodeLine("else if(vertex == triangle.C) {", null, 1, null);
- sc.addCodeLine("vertexToNeighbor1 = triangle.A.sub(vertex); // CA", null, 2, null);
- sc.addCodeLine("vertexToNeighbor2 = triangle.B.sub(vertex); // CB", null, 2, null);
- sc.addCodeLine("}", null, 1, null);
- sc.addCodeLine("", null, 0, null);
- sc.addCodeLine("// they are on opposite sides", null, 1, null);
- sc.addCodeLine("// if the dot product is less than zero", null, 1, null);
- sc.addCodeLine("boolean isOppositeNeighbor1 = ", null, 1, null);
- sc.addCodeLine("vertexToCenter.dot(vertexToNeighbor1) < 0;", null, 2, null);
- sc.addCodeLine("boolean isOppositeNeighbor2 = ", null, 1, null);
- sc.addCodeLine("vertexToCenter.dot(vertexToNeighbor2) < 0;", null, 2, null);
- sc.addCodeLine("", null, 0, null);
- sc.addCodeLine("return circle.radius < distToCenter", null, 1, null);
- sc.addCodeLine("&& isOppositeNeighbor1 && isOppositeNeighbor2;", null, 2, null);
- } // showSourceCodeVertexSA()
- public void showSourceCodeEdgeSA() {
- // first set the visual properties for the source code
- SourceCodeProperties scProps = new SourceCodeProperties();
- scProps.set(AnimationPropertiesKeys.CONTEXTCOLOR_PROPERTY, Color.BLUE);
- scProps.set(AnimationPropertiesKeys.FONT_PROPERTY, new Font("Monospaced", Font.PLAIN, 12));
- scProps.set(AnimationPropertiesKeys.HIGHLIGHTCOLOR_PROPERTY, Color.RED);
- scProps.set(AnimationPropertiesKeys.COLOR_PROPERTY, Color.BLACK);
- // now create the source code entity
- sc = lang.newSourceCode(new Coordinates(10, 50), "sourceCode", null, scProps);
- // add code lines (the actual sorting algo)
- // parameters: code itself, name (can be null), indention level, display options
- sc.addCodeLine("boolean isEdgeSA(Circle circle, Triangle triangle, Vector2f edge, Vector2f start, Vector2f end, Vector2f other) {", null, 0, null);
- sc.addCodeLine("Vector2f normalizedEdge = edge.normalize();", null, 1, null);
- sc.addCodeLine("Vector2f vecToCircle;", null, 1, null);
- sc.addCodeLine("", null, 0, null);
- sc.addCodeLine("if(edge == triangle.edgeAB) {", null, 1, null);
- sc.addCodeLine("vecToCircle = circle.center.sub(triangle.A);", null, 2, null);
- sc.addCodeLine("}", null, 1, null);
- sc.addCodeLine("else if(edge == triangle.edgeAC) {", null, 1, null);
- sc.addCodeLine("vecToCircle = circle.center.sub(triangle.A);", null, 2, null);
- sc.addCodeLine("}", null, 1, null);
- sc.addCodeLine("else if(edge == triangle.edgeBC) {", null, 1, null);
- sc.addCodeLine("vecToCircle = circle.center.sub(triangle.B);", null, 2, null);
- sc.addCodeLine("}", null, 1, null);
- sc.addCodeLine("float dot = normalizedEdge.dot(vecToCircle);", null, 1, null);
- sc.addCodeLine("Vector2f closestPointToCircle;", null, 1, null);
- sc.addCodeLine("if(dot <= 0) {", null, 1, null);
- sc.addCodeLine("closestPointToCircle = start;", null, 2, null);
- sc.addCodeLine("}", null, 1, null);
- sc.addCodeLine("else if(dot >= edge.length()) {", null, 1, null);
- sc.addCodeLine("closestPointToCircle = end;", null, 2, null);
- sc.addCodeLine("}", null, 1, null);
- sc.addCodeLine("else {", null, 1, null);
- sc.addCodeLine("closestPointToCircle = ", null, 2, null);
- sc.addCodeLine("normalizedEdge.mul(dot).add(start);", null, 3, null);
- sc.addCodeLine("}", null, 1, null);
- sc.addCodeLine("", null, 0, null);
- sc.addCodeLine("// check if the other vertex", null, 1, null);
- sc.addCodeLine("// (the one that is not part of the current edge)", null, 1, null);
- sc.addCodeLine("// and the circle-center lie on opposite sides of the edge", null, 1, null);
- sc.addCodeLine("Vector2f vecFromClosestPointToCircle = ", null, 1, null);
- sc.addCodeLine("circle.center.sub(closestPointToCircle);", null, 2, null);
- sc.addCodeLine("Vector2f vecFromClosestPointToOtherVertex = ", null, 1, null);
- sc.addCodeLine("other.sub(closestPointToCircle); ", null, 2, null);
- sc.addCodeLine("boolean isOppositeOtherVertex = vecFromClosestPointToCircle.dot(vecFromClosestPointToOtherVertex) < 0;", null, 1, null);
- sc.addCodeLine("", null, 0, null);
- sc.addCodeLine("return circle.radius < vecFromClosestPointToCircle.length() && isOppositeOtherVertex;", null, 1, null);
- } // showSourceCodeEdgeSA()
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement