1. Member Join Date
Nov 2012
Posts
18
Rep Power
0

## Triangle coordinate calculating

Hi All,
I have a (mathematical) question. I have a Boid with two vectors. One vector is representing the position (x,y) and the other vector representing the direction (i,j). I want to visualize the Boid with a triangle centered around the position and facing the direction. The black point is the position vector, the red arrow represents the direction vector. The purple and orange dots are the three points needed to render the (blue) triangle.

As the direction vector changes the triangle should rotate. For instance: So, given a position and a direction, the triangle points are: My question is how I can calculate these three points. I came up with one possibility to calculate the front point.
The front triangle has a length of 3 from the position. Also, it is in the same direction as the direction vector. So, I can normalize the direction vector and scale it by 3 to get the point in front of the position vector. Do you know smarter (CPU wise) ways to calculate this point?

For the two rear points, I have two theories. However, I do not know the math or which of the two is faster (CPU wise). Could you help me, please?

Method 1: calculate based on the direction vector.
For the rear points of the triangle, we know the angle of the triangle (with these ratios it is 45 degrees) and if we use the direction vector, we can calculate two new vectors. Also, we can calculate the length of the side, which is = sqrt(40) ≈ 6,3246. So, we can use the same method: normalize the two secondary vectors and scale them by sqrt(40).

Method 2 : use the radiant.
If you map the four standard poses on top of each other, two circles are shown. Based on the direction vector the front point is somewhere on the purple circle. The two rear points are somewhere on the orange circle. R1 = 3, as we saw earlier. R2 ≈ 2,8284. So, if we calculate two vectors from the position to the rear, using the angle between the direction vector and the new vector. This should be 135 degrees, if we use the ratio of R1:R2 = 3:sqrt(8). Can someone verify my methods. Also, are there better ways (in terms of less CPU usage) to calculate the three triangle points?

Vinvar
Last edited by Vinvar; 08-12-2017 at 01:07 PM.  Reply With Quote

2. ## Re: Traingle coordinates calculating

You'll have to wait until our mathematician comes along.
I'm only a java programmer and don't see any java programming question here.  Reply With Quote

3. Member Join Date
Nov 2012
Posts
18
Rep Power
0

## Re: Traingle coordinates calculating

I created some code. Code is tested and works (meaning: it is compilable and runnable).

First we have a Boid class and a Triangle class. The Triangle class holds the points needed to visualise the Boid.
Java Code:
```/**
* Class to store data about a triangle.
*
* @author Vinvar
* @version 1.0
* @since August 12th, 2017 ({@code build 1}).
*/
public class Triangle {
// Number of points a triangle has.
public static final int trianglePoints = 3;

// Array of points, representing the Triangle.
// The points are relative to the Boid's position.
public float[] xPoints;
public float[] yPoints;

public Triangle() {
xPoints = new float[trianglePoints];
yPoints = new float[trianglePoints];
}

// ..Getters & Setters...
}```
Java Code:
```import java.awt.Color;
import java.awt.Graphics2D;

/**
* Class to store data about a Boid.
*
* @author Vinvar
* @version 1.0
* @since August 12th, 2017 {@code build 1}
*/
public class Boid {

public Vector2f position, velocity;

public Triangle visualisationTriangle;

// Size of the helper points to render the position and trianglePoints.
public static final int pointSize = 20;

public Boid(Vector2f pos, Vector2f vel) {
position = pos;
velocity = vel;

visualisationTriangle = new Triangle();
}

// Every time a tick has been done, this method is called
public void setTriangle() {
// Front point of triangle
Vector2f normalisedVelocity = new Vector2f(velocity.x, velocity.y);
normalisedVelocity.normalise();

Vector2f front = normalisedVelocity.scale(3 * TriangleCoordinate.gridSize);
visualisationTriangle.xPoints = front.x;
visualisationTriangle.yPoints = front.y;

// TODO
// Point rearLeft = ??;

// TODO
// Point rearRight = ??;
}

// ... draw methods ...

/* Method to draw the parameters (position & velocity) of the Boid. */
public void drawBoid(Graphics2D graphics2D) {
// draw position of Boid
graphics2D.setColor(Color.BLACK);
graphics2D.fillOval((int) position.x - (pointSize / 2), (int) position.y - (pointSize / 2), pointSize,
pointSize);

// draw velocity of Boid
graphics2D.setColor(Color.RED);
graphics2D.drawLine((int) position.x, (int) position.y, (int) (position.x + (velocity.x * 100)),
(int) (position.y + (velocity.y * 100)));
}

/*
* Method to draw the parameters (front, rearLeft and rearRight) of the
* triangleVisualisation.
*/
public void drawTrianglePoints(Graphics2D graphics2D) {
// Draw front point
graphics2D.setColor(new Color(139, 0, 139)); // Dark purple
graphics2D.fillOval((int) (position.x + visualisationTriangle.xPoints - (pointSize / 2)),
(int) (position.y + visualisationTriangle.yPoints - (pointSize / 2)), pointSize, pointSize);

// Draw rearRight point
graphics2D.setColor(Color.ORANGE);
// g.drawLine();

// Draw rearLeft point
graphics2D.setColor(Color.ORANGE);
// g.drawLine();
}

/* Method to draw the visualisationTriangle to the Boid. */
public void drawTriangle(Graphics2D graphics2D) {
graphics2D.setColor(Color.BLUE);
// TODO first the three points in visualisationTriangle should be calculated correctly.
// graphics2D.drawPolygon(visualisationTriangle.xPoints, visualisationTriangle.yPoints, Triangle.trianglePoints);
}

// ...Getters & setters...
}```

And here we have a class which creates a Boid and a window the visualise what is happening. The class changes the velocity to all directions and calculates/renders the visualisationTriangle.
Java Code:
```import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;
import javax.swing.JPanel;

/**
* TriangleCoordinate is a demo to visualise a Boid facing its velocity at all
* https://www.java-forums.org/java-2d/97324-traingle-coordinates-calculating.html
*
* ToDo
* <ul>
* <li>Fix issues</li>
* <li>Move the front of the visualisationTriangle along with the velocity.</li>
* <li>Calculate and move the rearLeft and rearRight point of the
* visualisationTriangle.</li>
* </ul>
*
* Current issues:
* <ul>
* <li>The velocity does not walks smoothly along an imaginary circle. At the
* beginning it switches between positive and negative. Later, the velocity
* becomes a random point.</li?<li>The velocity decreases.</li>
* </ul>
*
* @author Vinvar
* @version 1.0
* @since August 12th, 2017 {@code build 1}
*/
public class TriangleCoordinate {

// MainWindow parameters
private JFrame mainWindow;
private static final int WIDTH = 300;
private static final int HEIGHT = WIDTH;
private static final Dimension windowSize = new Dimension(WIDTH, HEIGHT);

// Parameters to render to/with.
private JPanel mainPanel;
private BufferedImage bufferedImage;
private Graphics2D graphics2D;

// Grid parameters
public static final int gridSize = 25;

// Boid parameters
private Boid boid;

public TriangleCoordinate() {
// Set up Boid
boid = new Boid(new Vector2f(WIDTH / 2f, HEIGHT / 2f), new Vector2f(0f, -6f));

// Calculate the Boid's visualisation.
boid.setTriangle();

initRenderer();

faceAllDirections();
}

/* Method to set up the window, panel, bufferedImage and Graphics2D object. */
private void initRenderer() {
mainPanel = new JPanel();
mainPanel.setPreferredSize(windowSize);
bufferedImage = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_ARGB);
graphics2D = (Graphics2D) bufferedImage.getGraphics();

mainWindow = new JFrame("TriangleCoordinate");
mainWindow.setPreferredSize(windowSize);

mainWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainWindow.pack();
mainWindow.setVisible(true);
}

/*
* Method to rotate the velocity and check if the visualisation changes
* accordingly.
*/
private void faceAllDirections() {
// How many degrees do the want to increment each tick.
int incrementAngleperTick = 1;

// Make a full circle (aka: check all directions).
for (int currentAngle = 0; currentAngle <= 360; currentAngle += incrementAngleperTick) {
// Change the current angle from degrees to radians.

// Calculate the new velocity
float xOld = boid.velocity.x;

// Calculate the Boid's visualisation accordingly.
boid.setTriangle();

// Repaint the bufferedImage.
bakeScene();
drawScene();

// Wait one tenth of a second (so my eyes can follow the progress).
try {
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

/* Method to bake the next bufferedImage. */
public void bakeScene() {
graphics2D.clearRect(0, 0, WIDTH, HEIGHT);
graphics2D.setBackground(Color.WHITE);

drawGrid();

boid.drawBoid(graphics2D);

boid.drawTrianglePoints(graphics2D);

boid.drawTriangle(graphics2D);
}

/* Method to draw a grid on the JPanel. */
private void drawGrid() {
graphics2D.setColor(Color.LIGHT_GRAY);

// Can be one loop as WDITH = HEIGHT.
for (int i = 0; i <= TriangleCoordinate.HEIGHT; i += gridSize) {
graphics2D.drawLine(0, i, TriangleCoordinate.WIDTH, i);
graphics2D.drawLine(i, 0, i, TriangleCoordinate.HEIGHT);
}
}

/* Method to draw (thus show) the next bufferedImage to the mainPanel. */
private void drawScene() {
Graphics g2 = mainPanel.getGraphics();
g2.drawImage(bufferedImage, 0, 0, WIDTH, HEIGHT, null);
g2.dispose();
}

public static void main(String[] args) {
new TriangleCoordinate();
}
}```
My first question would be; why are the velocity and the frontPoint not nicely 'walking' in a circle around the boid.position?  Reply With Quote

4. ## Re: Traingle coordinates calculating

The posted code does not compile without errors (missing class) to be able to execute it for testing.

Can you make a SSCCE?  Reply With Quote

5. Member Join Date
Nov 2012
Posts
18
Rep Power
0

## Re: Traingle coordinates calculating Originally Posted by Norm The posted code does not compile without errors (missing class) to be able to execute it for testing.

Can you make a SSCCE?
Norm, thank you for looking at it and I am sorry about me forgetting the Vector2f class. I was trying to make a SSCCE and I thought this was as SSCCE it can be without stop making sense. How would you make this (even more) SSCCE? If you want I can leave the render part (JFrame, etc) out of it. However, I think it would be much harder to see what is happening, looking at values in the console.

Missing class:
Java Code:
```/**
* A 2D Vector where the variables are floats.
*
* @author Vinvar
* @version 1.0
* @since August 12th, 2017 {@code build 1}
*/
public class Vector2f {

/** the x-component of this vector **/
public float x;
/** the y-component of this vector **/
public float y;

/**
* Constructs a Vector2f with the given components
*
* @param x
*            The x-component
* @param y
*            The y-component
*/
public Vector2f(float x, float y) {
this.x = x;
this.y = y;
}

public float lengthSquared() {
return (float) Math.sqrt(x * x + y * y);
}

public Vector2f normalise() {
float squaredLength = lengthSquared();
if (squaredLength != 0) {
x /= squaredLength;
y /= squaredLength;
}
return this;
}

public Vector2f scale(float scalar) {
x *= scalar;
y *= scalar;

return this;
}
}```  Reply With Quote

6. ## Re: Traingle coordinates calculating

Take a look at the recommended way to write custom painting in Swing: Lesson: Performing Custom Painting (The Javaâ¢ Tutorials > Creating a GUI With JFC/Swing)
Basically, the code overrides a GUI component's paintComponent method where the output is drawn to the GUI. Other methods build what is to be shown and call repaint that causes the paintComponent method to be called where the new display is shown. Movement is created by the timing between calls to repaint.  Reply With Quote

7. Member Join Date
Nov 2012
Posts
18
Rep Power
0

## Re: Traingle coordinates calculating

I got rid of the swing components (yes, it could have been better coded but it is not the main problem ).

I redid the TriangleCoordinate and Boid class. Triangle and Vector2f are unchanged.
Java Code:
```/**
* TriangleCoordinate is a demo to visualise a Boid facing its velocity at all
* https://www.java-forums.org/java-2d/97324-traingle-coordinates-calculating.html
*
* ToDo
* <ul>
* <li>Fix issues</li>
* <li>Move the front of the visualisationTriangle along with the velocity.</li>
* <li>Calculate and move the rearLeft and rearRight point of the
* visualisationTriangle.</li>
* </ul>
*
* Current issues:
* <ul>
* <li>The velocity does not walks smoothly along an imaginary circle. At the
* beginning it switches between positive and negative. Later, the velocity
* becomes a random point.</li?<li>The velocity decreases.</li>
* </ul>
*
* @author Vinvar
* @version 1.0
* @since August 12th, 2017 {@code build 2}
*/
public class TriangleCoordinate {

// Boid parameters
private Boid boid;

public TriangleCoordinate() {
System.out.println("Testing the direction the Boid is facing.\n");
System.out.println(
"Outcome should be:\n Current angle(0)       = front( 0, 3).\n Current angle(90)      = front( 3, 0).\n Current angle(180/-0)  = front( 0,-3).\n Current angle(270/-90) = front(-3, 0).");
System.out.println(" At angles in between the front(x,y) should interpolate between the values.\n");

// Set up Boid
boid = new Boid(new Vector2f(0f, 0f), new Vector2f(0f, -6f));

// Calculate the Boid's visualisation.
boid.setTriangle();

faceAllDirections();
}

/*
* Method to rotate the velocity and check if the visualisation changes
* accordingly.
*/
private void faceAllDirections() {
// How many degrees do the want to increment each tick.
int incrementAngleperTick = 1;

// Make a full circle (aka: check all directions).
System.out.println("...Start simulation...");
for (int currentAngle = 0; currentAngle < 360; currentAngle += incrementAngleperTick) {
// Change the current angle from degrees to radians.

// Calculate the new velocity
float xOld = boid.velocity.x;

// Calculate the Boid's visualisation accordingly.
boid.setTriangle();

// Print output
System.out.printf("Current angle (%s) = front (%s,%s).\n",
currentAngle, boid.visualisationTriangle.xPoints, boid.visualisationTriangle.yPoints);
}
}

public static void main(String[] args) {
new TriangleCoordinate();
}
}```
Java Code:
```/**
* Class to store data about a Boid.
*
* @author Vinvar
* @version 1.0
* @since August 12th, 2017 {@code build 2}
*/
public class Boid {

public Vector2f position, velocity;

public Triangle visualisationTriangle;

// Size of the helper points to render the position and trianglePoints.
public static final int pointSize = 20;

public Boid(Vector2f pos, Vector2f vel) {
position = pos;
velocity = vel;

visualisationTriangle = new Triangle();
}

// Every time a tick has been done, this method is called
public void setTriangle() {
// Front point of triangle
Vector2f normalisedVelocity = new Vector2f(velocity.x, velocity.y);
normalisedVelocity.normalise();

Vector2f front = normalisedVelocity.scale(3);
visualisationTriangle.xPoints = front.x;
visualisationTriangle.yPoints = front.y;

// TODO
// Point rearLeft = ??;

// TODO
// Point rearRight = ??;
}

// ...Getters & setters...
}```
At the first three lines of the simulation the first problem is shown already. It is switching between positive and negative. Also, the expected outcomes are not
Java Code:
```Outcome should be:
Current angle(0)       = front( 0, 3).
Current angle(90)      = front( 3, 0).
Current angle(180/-0)  = front( 0,-3).
Current angle(270/-90) = front(-3, 0).

...Start simulation...
Current angle (0) = front (0.0,3.0).
Current angle (1) = front (-0.05235722,-2.9995432).
Current angle (2) = front (0.052421063,2.9995418).
Current angle (3) = front (-0.10482629,-2.998168).
Current angle (4) = front (0.105082646,2.998159).

Current angle (90) = front (2.1213202,-2.1213202).

Current angle (180) = front (-2.7353E-40,2.7353E-40).

Current angle (270) = front (0.0,0.0).```  Reply With Quote

8. ## Re: Traingle coordinates calculating

It is switching between positive and negative
Where are the values being computed? Try debugging that code to see why it is switching its sign.  Reply With Quote

9. Senior Member Join Date
Jan 2013
Location
Northern Virginia, United States
Posts
6,226
Rep Power
14

## Re: Traingle coordinates calculating

Not certain what I can add to your math approach other than adjusting the origin in the equations.

Take the following:

You have a point at (x,y) and you want to rotate it about (sx, sy) by some angle A.

x1 = sx + (x - sx)cos(A) - (y - sy)sin(A);
y1 = sy + (x - sx)sin(A) + (y - sy)cos(A);

where (x1,y1) is the new position. If you are rotating around (0,0) then sx and sy fall out of the equation.

But you can also do the following:

Stuff the points in a Polygon instance; create an AffineTransform rotate instance; and get
the Polygon Pathiterator, applying the transform as the argument. Then you iterate over the path to get
the transformed points. Note: this is the only way I have done it in the past since there is no obvious way
available to get a list of the transformed coordinates.

There will still be some slight errors. For example, when you rotate (100,100) 45 degrees clockwise, it should be (141..., 0).
But the 0 is actually a very small non-zero number.

Regards,
Jim
Last edited by jim829; 08-12-2017 at 06:22 PM.  Reply With Quote

10. Member Join Date
Nov 2012
Posts
18
Rep Power
0

## Re: Traingle coordinates calculating

Hi All,

I solved the issue with Norm's and Jim829's help. Thanks!

As said earlier, the front and rear point will move following a circular pattern. Looking at it, at any given time the x value of the front point is within the radius. Whatever the value of x, the y value of the front point will also be within the radius. Thus, x and y values of the front point will vary between -3 and 3.

So, if x moves from -3 to 3 and back, this can be visually represented by a parabola. Which made me think of the standard sinus and the cosinus parabolas. If we multiple the standard sinus and cosinus with the radius of the front point, we get the relative difference between the position of the Boid and the front point.
Java Code:
```// Distance between the front point and the position.
public static final float RADIUS_FRONT = 3f;

(...)

(...)

// Front point of triangle (relative to the position of the Boid).
bodyVisualisation.xPoints = xDelta;
bodyVisualisation.yPoints = yDelta;```
The angleInRadians can be calculated by doing
Java Code:
`double angleInRadians = Math.toRadians(currentAngle + UP_VECTOR_CORRECTION);`
To get the angleInRadians, you'll need the currentAngle. The current angle can be calculated with Math.atan2.
Java Code:
`double currentAngle = Math.toDegrees(Math.atan2(0 + rotation.x, 0 - rotation.y));`
And that is it, basically. If we store xDelta and yDelta to the xPoints[] and yPoints[] of the Boid's triangle, we have the offset of the front point. The same math can be applied to get the x and y value of the two rear points.

To be complete, hereby the complete demo code:
Boid class, in the setTriangle() method is where the points are calculated
Java Code:
```/**
* Class to store data about a Boid.
*
* @author Vinvar
* @version 1.1
* @since August 13th, 2017 {@code build 3}
*/
public class Boid {

/*
* Normally, angle(0) is to the right. Correct it so upwards is equal to
* angle(0).
*/
public static final int UP_VECTOR_CORRECTION = -90;
/*
* The rear points are not perpendicular from the rotation. Therefore, add an
* angle correction.
*/
public static final int REAR_ANGLE_CORRECTION = 45;
// Distance between the front point and the position.
public static final float RADIUS_FRONT = 3f;
// Distance between the rear points and the position.
public static final float RADIUS_BACK = (float) Math.sqrt(8);

// Every Boid has a position, rotation (and velocity but it is not needed in this demo.)
public Vector2f position, rotation;

// A triangle visualising the 'body' of the Boid.
public Triangle bodyVisualisation;

public Boid(Vector2f pos, Vector2f rot) {
position = pos;
rotation = rot;

bodyVisualisation = new Triangle();
}

/* Set the triangle according to the current rotation of the Boid. */
public void setTriangle() {

// Not needed in this demo: rotation.normalise();
double currentAngle = Math.toDegrees(Math.atan2(0 + rotation.x, 0 - rotation.y));

// Change the current angle from degrees to radians.

// Calculate the delta on both axis for the front point.

// Front point of triangle (relative to the position of the Boid).
bodyVisualisation.xPoints = xDelta;
bodyVisualisation.yPoints = yDelta;

// Change the current angle from degrees to radians
// Also, include the difference between the currentAngle and the rearLeft angle.

// Calculate the delta on both axis for the rear point.

// Rear left point of triangle (relative to the position of the Boid).
bodyVisualisation.xPoints = xDelta;
bodyVisualisation.yPoints = yDelta;

// Change the current angle from degrees to radians.
// Also, include the difference between the currentAngle and the rearRight angle.

// Calculate the delta on both axis for the rear point.

// Rear right point of triangle (relative to the position of the Boid).
bodyVisualisation.xPoints = xDelta;
bodyVisualisation.yPoints = yDelta;
}

// ...Getters & setters...
}```
TriangleCoordinate class. Just a simple (quick and dirty) helper class to test the Boid class.
Java Code:
```import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;
import javax.swing.JPanel;

/**
* TriangleCoordinate is a demo to visualise a Boid facing its rotation at all
* https://www.java-forums.org/java-2d/97324-traingle-coordinates-calculating.html
*
* Current issues:
* <ul>
* <li>No issues known.</li>
* </ul>
*
* @author Vinvar
* @version 1.1
* @since August 13th, 2017 {@code build 3}
*/
public class TriangleCoordinate {

// MainWindow parameters
private JFrame mainWindow;
private static final int WIDTH = 300;
private static final int HEIGHT = WIDTH;
private static final Dimension windowSize = new Dimension(WIDTH, HEIGHT);

// Parameters to render to/with.
private JPanel mainPanel;
private BufferedImage bufferedImage;
private Graphics2D graphics2D;

// Grid parameters
public static final int GRID_SIZE = 25;

// Boid parameters
private Boid boid;
public static final int BOID_POINT_SIZE = 20;

public TriangleCoordinate() {
System.out.println("Testing the direction the Boid is facing.\n");
System.out.println(
"Outcome should be:\n Current angle(0)       = front( 0,-3), rearLeft( 2,-2), rearRight(-2,-2).");
System.out.println(" Current angle(90)      = front( 3, 0), rearLeft( 2, 2), rearRight( 2,-2).");
System.out.println(" Current angle(180/-0)  = front( 0, 3), rearLeft(-2, 2), rearRight( 2, 2).");
System.out.println(" Current angle(270/-90) = front(-3, 0), rearLeft(-2,-2), rearRight(-2, 2).");
System.out.println(" At angles in between the front(x,y) should interpolate between the values.\n");

// Set up Boid
boid = new Boid(new Vector2f(WIDTH / 2f, HEIGHT / 2f), new Vector2f(0f, -6f));

// Calculate the Boid's visualisation.
boid.setTriangle();

initRenderer();

faceAllDirections();
}

/* Method to set up the window, panel, bufferedImage and Graphics2D object. */
private void initRenderer() {
mainPanel = new JPanel();
mainPanel.setPreferredSize(windowSize);
bufferedImage = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_ARGB);
graphics2D = (Graphics2D) bufferedImage.getGraphics();

mainWindow = new JFrame("TriangleCoordinate");
mainWindow.setPreferredSize(windowSize);

mainWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainWindow.pack();
mainWindow.setVisible(true);
}

/*
* Method to rotate the direction and check if the visualisation changes
* accordingly.
*/
private void faceAllDirections() {
// How many degrees do the want to increment each tick.
int incrementAngleperTick = 1;

// Make a full circle (aka: check all directions).
System.out.println("...Start simulation...");
for (int currentAngle = 0; currentAngle <= 360; currentAngle += incrementAngleperTick) {
// Stub method to change the rotation of the Boid.
// Normally the velocity will change and with it the rotation.
// As the rotation changes, I want to...
setRotation(currentAngle);

// ... calculate the Boid's visualisation accordingly.
boid.setTriangle();

// Output to console
if (currentAngle % 90 == 0) {
System.out.printf(" Current angle(%s) = front(%s, %s), rearLeft(%s,%s), rearRight(%s,%s).\n",
currentAngle, Math.round(boid.bodyVisualisation.xPoints),
Math.round(boid.bodyVisualisation.yPoints), Math.round(boid.bodyVisualisation.xPoints),
Math.round(boid.bodyVisualisation.yPoints), Math.round(boid.bodyVisualisation.xPoints),
Math.round(boid.bodyVisualisation.yPoints));
}
// Repaint the bufferedImage.
bakeScene();
drawScene();

// Wait one hundredth of a second (so my eyes can follow the progress).
try {
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("...End of simulation...");
}

/*
* Method to change the rotation of the Boid.
*
* This method is a stub method. Normally a steering force (or something alike)
* will change the velocity and with it the rotation of the Boid.
*/
private void setRotation(int currentAngle) {
// Calculate the difference between the upwards angle and the currentAngle.
// Also, change the current angle from degrees to radians.

// Calculate the delta on both axis.

// Set the new rotation...
boid.rotation = new Vector2f(xDelta, yDelta);
}

/* Method to bake the next bufferedImage. */
public void bakeScene() {
graphics2D.clearRect(0, 0, WIDTH, HEIGHT);
graphics2D.setBackground(Color.WHITE);

drawGrid();

drawBoid();

drawTrianglePoints();

drawTriangle();
}

/* Method to draw a grid on the JPanel. */
private void drawGrid() {
graphics2D.setColor(Color.LIGHT_GRAY);

// Can be one loop as WDITH = HEIGHT.
for (int i = 0; i <= TriangleCoordinate.HEIGHT; i += GRID_SIZE) {
graphics2D.drawLine(0, i, TriangleCoordinate.WIDTH, i);
graphics2D.drawLine(i, 0, i, TriangleCoordinate.HEIGHT);
}
}

// ... draw methods ...

/* Method to draw the parameters (position & rotation) of the Boid. */
public void drawBoid() {
// draw position of Boid
graphics2D.setColor(Color.BLACK);
graphics2D.fillOval((int) boid.position.x - (BOID_POINT_SIZE / 2),
(int) boid.position.y - (BOID_POINT_SIZE / 2), BOID_POINT_SIZE, BOID_POINT_SIZE);

// draw rotation of Boid
graphics2D.setColor(Color.RED);
graphics2D.drawLine((int) boid.position.x, (int) boid.position.y,
(int) (boid.position.x + (boid.rotation.x * (GRID_SIZE * 10))),
(int) (boid.position.y + (boid.rotation.y * (GRID_SIZE * 10))));
}

/*
* Method to draw the parameters (front, rearLeft and rearRight) of the
* triangleVisualisation.
*/
public void drawTrianglePoints() {
// Draw front point
graphics2D.setColor(new Color(139, 0, 139)); // Dark purple
graphics2D.fillOval(
(int) (boid.position.x + boid.bodyVisualisation.xPoints * GRID_SIZE - (BOID_POINT_SIZE / 2)),
(int) (boid.position.y + boid.bodyVisualisation.yPoints * GRID_SIZE - (BOID_POINT_SIZE / 2)),
BOID_POINT_SIZE, BOID_POINT_SIZE);

// Draw rearLeft point
graphics2D.setColor(Color.ORANGE);
graphics2D.fillOval(
(int) (boid.position.x - boid.bodyVisualisation.xPoints * GRID_SIZE - (BOID_POINT_SIZE / 2)),
(int) (boid.position.y - boid.bodyVisualisation.yPoints * GRID_SIZE - (BOID_POINT_SIZE / 2)),
BOID_POINT_SIZE, BOID_POINT_SIZE);

// Draw rearRight point
graphics2D.setColor(Color.ORANGE);
graphics2D.fillOval(
(int) (boid.position.x - boid.bodyVisualisation.xPoints * GRID_SIZE - (BOID_POINT_SIZE / 2)),
(int) (boid.position.y - boid.bodyVisualisation.yPoints * GRID_SIZE - (BOID_POINT_SIZE / 2)),
BOID_POINT_SIZE, BOID_POINT_SIZE);
}

/* Method to draw the visualisationTriangle to the Boid. */
public void drawTriangle() {

// Convert float[] to int[] as drawPolygon requires int[].
int[] intPointsX = new int;
int[] intPointsY = new int;

intPointsX = (int) (boid.position.x + (boid.bodyVisualisation.xPoints * GRID_SIZE));
intPointsY = (int) (boid.position.y + (boid.bodyVisualisation.yPoints * GRID_SIZE));

for (int i = 1; i < intPointsX.length; i++) {
intPointsX[i] = (int) (boid.position.x - (boid.bodyVisualisation.xPoints[i] * GRID_SIZE));
intPointsY[i] = (int) (boid.position.y - (boid.bodyVisualisation.yPoints[i] * GRID_SIZE));
}

// Draw polygon
graphics2D.setColor(Color.BLUE);
graphics2D.drawPolygon(intPointsX, intPointsY, Triangle.trianglePoints);
}

/* Method to draw (thus show) the next bufferedImage to the mainPanel. */
private void drawScene() {
Graphics g2 = mainPanel.getGraphics();
g2.drawImage(bufferedImage, 0, 0, WIDTH, HEIGHT, null);
g2.dispose();
}

public static void main(String[] args) {
new TriangleCoordinate();
}
}```
Triangle class, not changed
Java Code:
```/**
* Class to store data about a triangle.
*
* @author Vinvar
* @version 1.0
* @since August 12th, 2017 ({@code build 1}).
*/
public class Triangle {
// Number of points a triangle has.
public static final int trianglePoints = 3;

// Array of points, representing the Triangle.
// The points are relative to the Boid's position.
// Stored counter clockwise: front, rearLeft, rearRight.
public float[] xPoints;
public float[] yPoints;

public Triangle() {
xPoints = new float[trianglePoints];
yPoints = new float[trianglePoints];
}

// ..Getters & Setters...
}```
Vector2f class, not changed
Java Code:
```/**
* A 2D Vector where the variables are floats.
*
* @author Vinvar
* @version 1.0
* @since August 12th, 2017 {@code build 1}
*/
public class Vector2f {

/** the x-component of this vector **/
public float x;
/** the y-component of this vector **/
public float y;

/**
* Constructs a Vector2f with the given components
*
* @param x
*            The x-component
* @param y
*            The y-component
*/
public Vector2f(float x, float y) {
this.x = x;
this.y = y;
}

/**
*
* @return Float representing the length of the Vector2f.
*/
public float lengthSquared() {
return (float) Math.sqrt(x * x + y * y);
}

/**
* Method to normalise this Vecotr2f.
*
* @return Normalised Vector2f.
*/
public Vector2f normalise() {
float squaredLength = lengthSquared();
if (squaredLength != 0) {
x /= squaredLength;
y /= squaredLength;
}
return this;
}

/**
* Method to scale this Vector2f.
*
* @param scalar
*            Float of scale value.
* @return Scaled Vector2f.
*/
public Vector2f scale(float scalar) {
x *= scalar;
y *= scalar;

return this;
}

/**
* Converts this {@code Vector2f} to a string in the format {@code (x,y)}.
*
* @return a string representation of this object.
*/
@Override
public String toString() {
return "(" + x + "," + y + ")";
}
}```  Reply With Quote

triangle, triangle coordinates, vector 