- Home /
How to get a vector3 (postion) 1 unit away from another in the direction of a 3rd vector3?
It is highly possible that has been answered already, I'm terrible at vector math... So what I am trying to do is have the user drag a wall for placement, I want to generate the mesh. So I have the starting and ending points as vector3s. Let's say the wall has a width of 1. and the starting point happened to be (0, 0, 0) and the ending point was (0, 0, 5). I want to get the vertices:
(0.5f, 0, 0)
(-0.5f, 0, 0)
(0.5f, 0, 5)
(-0.5f, 0, 5)
So this will create a rectangle and then it is easy to extrude these points for the wall height. So this example will obviously be easy to calculate, but the user can drag the wall in any direction.
So here's what I thought of doing (but can't get it right) - Get start point - Get a 3rd vector above the start point (Vector3.Up * startpoint) - Get point perpendicular to the start point and up Point - Get a point 0.5f units away from the start vector in the direction of the perpendicular point - Get a point 0.5f units away from the start vector in the negative direction of the perpendicular point.
repeat these steps for end point.
Then I should have the 4 points for the base of my wall.
Anyway here's my broken code:
[System.Serializable]
public class Points
{
public Vector3 startingPoint, endingPoint;
}
public class PerpLines : MonoBehaviour
{
public Points points;
public GameObject positionSphere;
Vector3 upVector;
void Start()
{
upVector = Vector3.up + points.startingPoint;
Instantiate(positionSphere, points.startingPoint, Quaternion.identity);
Instantiate(positionSphere, points.endingPoint, Quaternion.identity);
Instantiate(positionSphere, upVector, Quaternion.identity);
}
public void ShowLines() // method is attached to a button to show lines
{
Debug.DrawLine(points.startingPoint, points.endingPoint, Color.blue, Mathf.Infinity);
Debug.DrawLine(points.startingPoint, upVector, Color.blue, Mathf.Infinity);
Vector3 perpPoint = CalculatePerp(points.startingPoint, points.endingPoint, upVector);
Instantiate(positionSphere, perpPoint, Quaternion.identity);
Debug.DrawLine(points.startingPoint, perpPoint, Color.red, Mathf.Infinity);
Vector3 halfPoint = GetFinalVector(perpPoint, points.startingPoint);
Instantiate(positionSphere, halfPoint, Quaternion.identity);
Debug.DrawLine(points.startingPoint, halfPoint, Color.yellow, Mathf.Infinity);
}
private Vector3 GetFinalVector(Vector3 perpPoint, Vector3 startingPoint)
{
Vector3 heading = startingPoint - perpPoint;
float distance = heading.magnitude;
Vector3 direction = heading / distance;
return direction;
}
private Vector3 CalculatePerp(Vector3 startingPoint, Vector3 endingPoint, Vector3 upVector)
{
Vector3 side1 = endingPoint - startingPoint;
Vector3 side2 = upVector - startingPoint;
Vector3 ret = Vector3.Cross(side1, side2);
return ret;
}
}
as you can see my red line isn't perpendicular to my blue ones and the yellow line should lie on top of the red one but only be 1 unit long.
If anyone has a better idea instead of my whole mathematical vector thing please do share!
Answer by Bunny83 · Jul 26, 2016 at 11:25 AM
With your cross product you calculate a direction that is perpendicular to the two given directions. You should add the result to your startpoint in order to get an actual point in the world.
Your "GetFinalVector" method just does a quite complicate "ormalize" ^^. There you actually "subtract" your startpoint to get a direction again. Now you again treat the direction vector like a position. Direction vectors without a reference point are relative to the world origin. This is what you see in both cases.
Your red vector is perpendicular to your two blue lines, but it actually starts at (0,0,0) (the world origin).
Your yellow vector is simply the normalized inverse of your red vector but again relative to the world origin.
Mathematically spoken there's no difference between direction and position vectors as they are just vectors. It just depends on the usage.
You should also be careful with variable names. "upVector" is usually used for directions but your is actually a point / position.
So finally to get a vector that is perpendicular to your two (blue) vectors that has a length of "1" you simply do the cross product and then normalize the result. This gives you a direction vector. This you can add to your startpoint to get a point that is one unit away from the start point.
private Vector3 CalculateNormal(Vector3 startingPoint, Vector3 endingPoint, Vector3 point3)
{
Vector3 side1 = endingPoint - startingPoint;
Vector3 side2 = point3 - startingPoint;
Vector3 ret = Vector3.Cross(side1, side2);
// return the normalized direction
return ret.normalized;
}
// [...]
Vector3 dir = CalculateNormal(points.startingPoint, points.endingPoint, upVector);
Vector3 point = points.startingPoint + dir;
Of course "dir" can be multiplied by any factor to get any desired distance. For example if you want to get the points that are +0.5 and -0.5 away you simply do:
Vector3 p1 = points.startingPoint + dir * 0.5f;
Vector3 p2 = points.startingPoint - dir * 0.5f;
Thanks a million! :) makes sense now. $$anonymous$$inus from a position to get a direction. Add to a direction to get a position. It's actually simple! and because vector3.normalize returns a vector with a magnitude of 1 I can times it by any number I need to. It's actually simple. I definitely learned something today!
Answer by rmassanet · Jul 26, 2016 at 07:42 AM
I didn't quite follow the problem, but, in order to get a point P
that is exactly one unit apart from another point A
in the direction defined by vector v
, simply do:
Vector3 P = A + v.normalized;
I haven't compiled, but you get the idea.