The angle between two vectors and The orientation from one Vector point to another Vector point

So is not the same if i do;

 let first = Point::new(20.0, 1.0);
let second = Point::new(1.0, 40.0);
let third = Point::new(-60.0, -1.0);


let value =  (second.y - first.y) * (second.x - first.x)
        - (third.x - first.x) * (third.y - first.y);

I changed the value calculation!

Well, I was under the assumption that this was 3D, hence why I used the cross product with the up vector. In 2D it becomes easier:
Use the angle between the two vectors and match using that.
Also, I'd discourage writing your own linear algebra operations; that's what cgmath/nalgebra are for.

1 Like

I tried your code but always is returning 0,and output is forward or backward every time...
You mean: The angle between point B and Point C,
and after matching the result if is > 0 than output right,else if < 0 output left, else forward or backward .. ?
Actually what i am saying, angle will be every time positive .. Maybe distance is the solution for the orientation ?

No, I'm saying the angle between the vector between a and b, and the vector between b and c.

let a = Point(...);
let b = Point(...);
let c = Point(...);

let v_ab = b - a;
let v_cb = c - b;

let angle = v_ab.angle(v_cb);
1 Like

So should look like this ;

   let point_a = Vector3 {
   x: 20.0,
  y: 1.0,
 z: 0.0,
 };

 let point_b = Vector3 {
 x: 1.0,
 y: 40.0,
 z: 0.0,
 };

 let point_c = Vector3 {
 x: -60.0,
 y: -1.0,
 z: 0.0,
 };

//Angle
println!("Angle of Point A & Point B is: {:?}", Deg::from(point_a.angle(point_b)));
println!("Angle of Point B & Point C is: {:?}", Deg::from(point_b.angle(point_c)));   
println!("Angle of Point A & Point B & Point C is: {:?}", 
Deg::from(point_a.angle(point_b) + point_b.angle(point_c)));

//Distance
println!("Distance between Point A to Point B is: {:?}", point_a.distance(point_b));
println!("Distance between Point B to point C is: {:?}", point_b.distance(point_c));

let v_ab = point_b - point_a;
let v_cb = point_c - point_b;

let angle = v_ab.angle(v_cb);

i am reading now The cross product can solve this, am i right ?

pub fn cross(self, other: Vector3<S>) -> Vector3<S> {
    Vector3::new(
        (self.y * other.z) - (self.z * other.y),
        (self.z * other.x) - (self.x * other.z),
        (self.x * other.y) - (self.y * other.x),
    )
}

No, my earlier reply is for 3D, and the reply I posted last before this post Is for 2D.

Also, there is a difference between a point and a vector, in that a vector can be thought of as a direction in space from the origin with a given length, and a point is just a point in space. Sure, you can freely convert between them, but if you do more linear algebra, there will be some distinctions (For example, translations don't apply to vectors, but do for points).

Yes, the cross product of the up vector with the first forward vector will produce a kind of "left" vector if I have my linear algebra correct. Then we look at how similar this "left" vector is through the dot product with the second vector. If it's +1, then it's identical, if it's -1, then they're exact opposites. Note that I'm talking in terms of normalized vectors, since that makes talking about directions easy. Also note that anything other than -1 and +1 could mean that the third point is pointing up or down or forwards or back, since we're now talking in 3D and there's a sphere that could be drawn between the endpoint of a vector and the endpoint of the negation of said vector. To use this image, anything on the "equator" of this sphere will have a dot product of 0 when the sample vector is normalized.

1 Like

I am trying to solve this really. Now i tried this one;

let angle1 = point_a.angle(point_b);
let angle2 = point_b.angle(point_c);

if angle1 > angle2 {
println!("go right");
}else if angle1 < angle2 {
println!("go left");
}else if angle1 == angle2 {
println!("go forward or backward")
}

output is "go left"

//

I tried this also;

  let point_a = Vector3 {
  x: 20.0,
  y: 1.0,
  z: 0.0,
 };

 let point_b = Vector3 {
 x: 1.0,
 y: 40.0,
 z: 0.0,
 };

 let point_c = Vector3 {
 x: -60.0,
 y: -1.0,
 z: 0.0,
 };

 let cross = Vector3::new(
 (point_b.y * point_c.z) - (point_b.z * point_c.y),
 (point_b.z * point_c.x) - (point_b.x * point_c.z),
 (point_b.x * point_c.y) - (point_b.y * point_c.x),
  );

output is " Vector3 [0.0, -0.0, 2399.0] "

https://stackoverflow.com/questions/3419341/how-to-calculate-turning-direction

check this out(is for C language)

I believe you have not read the entirety of my previous posts;

  • The method you use will differ between 2D and 3D.
  • There is a difference between Points and Vectors. If you change point_a to be a Point3, you will see you cannot take the angle between them. That is because they are thought of differently. Here is a vector, and here is a point. There is an arrow drawn for the vector because it is a direction with a magnitude (distance along direction). There is just a point for the point because it has no direction.

Lets walk through what your current code is doing:

  • We have points: Angle Problem
  • We take the angles between them, treating them as vectors: Angle Problem 2
    Oh no! This doesn't make sense. Why would we want the angle from the origin?

Lets walk through what I suggested in 2D:

  • We have points: Angle Problem
  • We take the vectors between the points: Angle Problem 3
  • We can now distinguish between left and right: Angle Problem 4
  • And with the vectors too: Angle Problem 5
    Now please try dragging C around. You will see that this makes the BC vector change. You can then use angles on these two vectors to figure out left/right/forward/back.
2 Likes

I don't have the time or ability to create a walkthrough example for the 3D code, and you may need someone on a math forum or someone on here who's better at explaining these kinds of things to help you understand the 3D code.

On a side note:
I am still unsure of whether you want 2D or 3D directions.

1 Like

I really appreciate your help , thank you so much! I am working with it,also I am a beginner in Rust programming, but I like rust so much, and i spend much time these days to learn it. I want 2D directions, you explained me quiet good, and I am working with it, now or later I will solve this,it is not quiet simple to do it :smiley: , I have a question how did you find the AB vector Angle Problem 3 ? (I am not so good in math, but you can explain me the calculation with the given values,which you found the ab vector)
B - A && C - B ?

The vector between two points is P2 - P1.
f_vector(I, K) finds the vector between two points using K - I, and v_AB is f_vector(A, B). Therefore, it is found with B - A.

1 Like

And for the right and left side, how did you find that here Angle Problem 5
(1, -1(right)) && (-1, 1(left)..

I found them by... annotating the left and right? I'm not quite sure what you mean. If the AB is forward, we now know what left and right are.

1 Like

I need your opinion for that what I did now, so simple;

let _first = Point::new(2.0, 3.0);
let second = Point::new(4.0, 3.0);
let third = Point::new(6.0, 1.0);


if second.y > third.y {
println!("To reach Point 3 turn right");
}else if second.y < third.y {
println!("To reach Point 3 turn left");
}else if second.y == third.y {
println!("To reach Point 3 walk forward");
}else {
println!("To reach Point 3 walk backward")
}

this is based in : Angle Problem 3

What do you think ?

I am working now for the backward

I believe that this level of detail regarding directions would be better suited for a math specific forum as though this is a rust specific forum. Someone on a math forum would most likely be better suited to explain what to do.

2 Likes

Actually I need only the orientation from point B to point C, and here is the solution(of course they are and other ways to do it),but this is my logic and it looks great! I will appreciate if you test it ! (Crate: arcs = "0.3.0"). Try every orientation by changing only the 'third' variable values!

use  arcs::Point;

fn main() {

let _first = Point::new(2.0, 3.0);
let second = Point::new(4.0, 3.0);
let third = Point::new(2.0,  -3.0);


if second.y > third.y && second.x < third.x {
println!("To reach Point 3 walk forward and turn right");
}else if second.y < third.y && second.x < third.x {
println!("To reach Point 3 walk forward and turn left");
}else if second.y == third.y && second.x < third.x {
println!("To reach Point 3 walk forward");
}else if second.y > third.y && second.x > third.x  {
println!("To reach Point 3 walk backward and turn left");
}else if second.y < third.y && second.x > third.x {
println!("To reach Point 3 walk backward and turn right");
}else if second.y == third.y && second.x > third.x {
println!("To reach Point 3 turn back and walk Straight on");
}

And here is the full code for angle,orientation,and distance to walk and when to turn;

    use cgmath::{prelude::*, Vector3, Deg};
    use  arcs::Point;

    fn main() {

    //Constructor   
    let point_a = Vector3 {
    x: 2.0,
    y: 3.0,
    z: 0.0,
    };
   
    let point_b = Vector3 {
    x: 4.0,
    y: 3.0,
    z: 0.0,
    };
   
    let point_c = Vector3 {
    x: 7.0,
    y: -4.0,
    z: 0.0,
    };
      
    
    //Angle
    /*println!("Angle of Point A & Point B is: {:?}", Deg::from(point_a.angle(point_b)));
    println!("Angle of Point B & Point C is: {:?}", Deg::from(point_b.angle(point_c)));*/  
 
    println!("Angle of Point A & Point B & Point C is: {:?}\n\n", 
    Deg::from(point_a.angle(point_b) + point_b.angle(point_c)));
        
    let _first = Point::new(2.0, 3.0);
    let second = Point::new(4.0, 3.0);
    let third = Point::new(7.0,  -4.0);
    let walk_point = Vector3 { //walk_point must be  the same with the second point
    x: 4.0,
    y: 3.0,
    z: 0.0,
    };
    let distance_to_walk = Vector3 { //x must be the same with third.x and y must be the same with second.y
    x: 7.0,
    y: 3.0,
    z: 0.0,
    };
    
    if second.y > third.y && second.x < third.x {
    println!("To reach Point 3 walk {:?}(cm/m/km) forward and turn right", walk_point.distance(distance_to_walk));
    }else if second.y < third.y && second.x < third.x {
    println!("To reach Point 3 walk {:?}(cm/m/km) forward and turn left", walk_point.distance(distance_to_walk));
    }else if second.y == third.y && second.x < third.x {
    println!("To reach Point 3 walk {:?}(cm/m/km) forward", walk_point.distance(distance_to_walk));
    }else if second.y > third.y && second.x > third.x  {
    println!("To reach Point 3 walk {:?}(cm/m/km) backward and turn left", walk_point.distance(distance_to_walk));
    }else if second.y < third.y && second.x > third.x {
    println!("To reach Point 3 walk {:?}(cm/m/km) backward and turn right", walk_point.distance(distance_to_walk));
    }else if second.y == third.y && second.x > third.x {
    println!("To reach Point 3 turn back and walk {:?}(cm/m/km) Straight on", walk_point.distance(distance_to_walk));
    }    
    }

@OptimisticPeach