Sign in to follow this  
Kram

Vector maths help

Recommended Posts

Im having a dilema calculating some vectors... It seems simple, but its just one of those days today! In 2d space, lets say I have an initial vector (x:1, y:1), at point (x:50, y:50) I would like to generate an array of vectors that "spray" out from that point (50, 50) in a 50 degrees range. Its hard to explain, but basically, I need to generate X new vectors, based on an angle A, starting at a point P, using the initial vector V. where P = (50,50) A = 50 (in degrees) X = 10 (10 new vectors) V = (1,1) directional vector can anyone please help me? Ive been drawing it out on my pad and paper, and I just seem to get it...

Share this post


Link to post
Share on other sites
There might be a better way, but you could use some trigonometry to do this:

for (A = 0; A < 360; A+=50)
Resultant = Vector2(cos(Pi*A/180)+P.x, sin(Pi*A/180)+P.y)

Just modify the above to suite your needs. If you want a greater directional vector, just put a coefficient in front of the sin/cos.

If you want to know why this works, draw out the triangles (and draw them with the same origin) with theta at 0, 50, 100, and so on to see how the outer tip of the triangles forms a circle.

Share this post


Link to post
Share on other sites
hi disanti, thanks for the help, I was already on the trigonometry path and was very confused about it any why my method wasnt working, which was the same as yours! However, after careful debugging, I found that it was just a rounding error...

Here is some code I have in Java:


double xpos = 60;
double ypos = 60;

double vec_y = ypos - 50;
double vec_x = xpos - 50;

double angle_deg = Math.toDegrees(Math.atan2(vec_y, vec_x));

if (angle_deg < 0)
angle_deg += 360;

double angle_rad = Math.toRadians(angle_deg);

System.out.println("angle_rad: " + angle_rad + " angle_deg: " + angle_deg);

double numOfVecsEachSide = 10;
double sprayAngle = 50;
double eachSideVecs = sprayAngle / 2;
double angleOfEachVec = eachSideVecs / numOfVecsEachSide;
double newAngle = angle_deg;

//rotate anti-clockwise
for (int i = 0; i < numOfVecsEachSide; i++){
newAngle += angleOfEachVec;
//find new vector
double new_xpos = (10 * Math.cos(Math.toRadians(newAngle))) + 50;
double new_ypos = (10 * Math.sin(Math.toRadians(newAngle))) + 50;

System.out.println("newAngle: "+ newAngle + " newx: " + new_xpos + " newy: " + new_ypos);
}

System.out.println("");
System.out.println("");

newAngle = angle_deg;
//rotate clockwise
for (int i = 0; i < numOfVecsEachSide; i++){
newAngle -= angleOfEachVec;
//find new vector

double new_xpos = (10 * Math.cos(Math.toRadians(newAngle))) + 50;
double new_ypos = (10 * Math.sin(Math.toRadians(newAngle))) + 50;

System.out.println("newAngle: "+ newAngle + " newx: " + new_xpos + " newy: " + new_ypos);
}



I think its working... let me know if its in-efficient or it can be better written.

Thanks for the help.

Share this post


Link to post
Share on other sites
Quote:
Original post by ppgamedev
What do you want to mean with:
*** Source Snippet Removed ***
???


hehe, ok so that was a bit of slack coding on my part, I had some constants that I was thinking about and instead of putting them into actual constants, I just hard coded the numbers not really thinking about the read-ability of that chunk of code.

Share this post


Link to post
Share on other sites
OK, I got it.

I think there is a mistake in:

double new_xpos = (10 * Math.cos(Math.toRadians(newAngle))) + 50;
double new_ypos = (10 * Math.sin(Math.toRadians(newAngle))) + 50;



It should be something like:

double module = Math.sqrt(10 * 10 + 10 * 10);

...

double new_xpos = (module * Math.cos(Math.toRadians(newAngle))) + 50;
double new_ypos = (module * Math.sin(Math.toRadians(newAngle))) + 50;



Never ever sacrifice readability when investigating a solution!!!

Unless you can prove with real data (profiling) that an obscure solution really improve the performance go always for a clear one.

My advice is to always use radians internally. Just translate to degrees only for UI.


This is my solution, do you like it?:

public class Main {

public static class Point2 {
public final double x;
public final double y;

public Point2(double x, double y) {
this.x = x;
this.y = y;
}

public String toString() {
return String.format("[%.3f, %.3f]", x, y);
}
}

public static interface Vector2 {
public double getX();
public double getY();
public Point2 getPosition();
public double getModule();
public double getAngle();
public Point2 getEnd();

public Vector2 rotate(double rotation);
}

public static abstract class AbstractVector2 implements Vector2 {
public String toString() {
return String.format("{ %s (%.3f, %.3f) (%.3f | %.3f o) }", getPosition(), getX(), getY(), getModule(), Math.toDegrees(getAngle()));
}
}

public static class CartesianVector2 extends AbstractVector2 {
private final Point2 position;
private final double x;
private final double y;

public CartesianVector2(Point2 position, double x, double y) {
this.position = position;
this.x = x;
this.y = y;
}
public CartesianVector2(Vector2 v) {
this(v.getPosition(), v.getX(), v.getY());
}
public CartesianVector2(Point2 position, Point2 end) {
this(position, end.x - position.x, end.y - position.y);
}

public double getX() {
return x;
}
public double getY() {
return y;
}
public Point2 getPosition() {
return position;
}
public double getModule() {
return Math.sqrt(x * x + y * y);
}
public double getAngle() {
return Math.atan2(y, x);
}
public Point2 getEnd() {
return new Point2(position.x + x, position.y + y);
}

public Vector2 rotate(double rotation) {
final double cos = Math.cos(rotation);
final double sin = Math.sin(rotation);
final double newX = x * cos - y * sin;
final double newY = x * sin + y * cos;
return new CartesianVector2(position, newX, newY);
}
}

public static class PolarVector2 extends AbstractVector2 {
private final Point2 position;
private final double module;
private final double angle;

public PolarVector2(Point2 position, double module, double angle) {
this.position = position;
this.module = module;
this.angle = angle;
}
public PolarVector2(Vector2 v) {
this(v.getPosition(), v.getModule(), v.getAngle());
}

public double getX() {
return module * Math.cos(angle);
}
public double getY() {
return module * Math.sin(angle);
}
public Point2 getPosition() {
return position;
}
public double getModule() {
return module;
}
public double getAngle() {
return angle;
}
public Point2 getEnd() {
return new Point2(position.x + getX(), position.y + getY());
}

public Vector2 rotate(double rotation) {
return new PolarVector2(position, module, angle + rotation);
}
}

public static void main(String[] args) {
final Point2 start = new Point2(50,50);
final Point2 end = new Point2(60,60);
final Vector2 vec = new CartesianVector2(start, end);
System.out.println(vec);

final int numOfVecsEachSide = 10;
final double sprayAngle = Math.toRadians(50);
doSpray(vec, numOfVecsEachSide, sprayAngle);
}

private static void doSpray(Vector2 vec, int numOfVecsEachSide, double sprayAngle) {
final double rotateAngle = sprayAngle / 2 / numOfVecsEachSide;
//rotate anti-clockwise
doRotation(vec, rotateAngle, numOfVecsEachSide);
//rotate clockwise
doRotation(vec, -rotateAngle, numOfVecsEachSide);
}

private static void doRotation(final Vector2 vec, double angle, int n) {
System.out.println();
Vector2 newVec = new PolarVector2(vec);
for (int i = 0; i < n; i++){
newVec = newVec.rotate(angle);
System.out.println(newVec);
}
}

}


Share this post


Link to post
Share on other sites
Hi ppgamedev, thanks for the thoughts, I did actually make a Point class that I'm using, although I called it Point2D, which makes life easier.

I'll keep it in Radians internally, thanks for the help.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this