Search Unity

Find a point on a "line" between two Vector3

Discussion in 'Scripting' started by tet2brick, Jun 21, 2012.

  1. tet2brick

    tet2brick

    Joined:
    Jun 24, 2009
    Posts:
    77
    Hello,

    I'have (again ^^) a problem of logic, more than scripting.

    I need to find a point on a line between two Vector3, placed on this line at x units of one of the Vector3.
    I see how to find the middle point betwen the two Vector3, but not to find an arbitrary points.

    Any idea?

    Thanks a lot :)
     
    folino9 likes this.
  2. SalvadorLimones

    SalvadorLimones

    Joined:
    May 11, 2012
    Posts:
    7
    Let us say you have two vectors A and B between which you want to find the point.

    1) Subtract the two vector (B-A) to get a vector pointing from A to B. Lets call this AB

    2) Normalize this vector AB. Now it will be one unit in length.

    3) You can now scale this vector to find a point between A and B. so (A + (0.1 * AB)) will be 0.1 units from A.
     
    Last edited: Jun 21, 2012
  3. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    Yep, but a quick note that step 3 should be;

    3) You can now scale this vector to find a point between A and B. so A + (0.1 * AB) will be 0.1 units from A.
     
    Novack likes this.
  4. Brian-Stone

    Brian-Stone

    Joined:
    Jun 9, 2012
    Posts:
    222
    To rephrase your problem... Given a line segment defined by end-point vectors A and B, calculate point P which lies on the line and is distance x from point A.

    You can simply use the Lerp() method to do that. The interpolation value, which is the last argument in the Lerp() call, is normally clamped between 0 and 1. So dividing x by the distance between A and B will do that for you. If x=0 then this method returns A, and if x=(A-B).Length() then it returns B, and if x is some positive distance between 0 and (A-B).Length() then the method returns a vector that is in between A and B at the given distance from point A.

    Code (csharp):
    1.  
    2. Vector3 P = Vector3.Lerp(A, B, x / (A-B).Length());
    3.  
    Here is the actual equation that is being calculating.
    P = x * (B - A) / |B - A| + A

    You may find it more convenient to code your own method,like this:
    C# code:
    Code (csharp):
    1.  
    2. public Vector3 LerpByDistance(Vector3 A, Vector3 B, float x)
    3. {
    4.     Vector3 P = x * Vector3.Normalize(B - A) + A;
    5.     return P;
    6. }
    7.  
     
  5. tet2brick

    tet2brick

    Joined:
    Jun 24, 2009
    Posts:
    77
    Yes!

    Thanks to all of you, it's working perfectly! :)
     
    Last edited: Jun 21, 2012
  6. ZoomDomain

    ZoomDomain

    Joined:
    Aug 30, 2012
    Posts:
    150
    I don't really understand the answer, because if you have a line going from 0.1 ,0 ,0 to 0.3 ,0 ,0, and then you make a vector from it, like 0.2 ,0 , 0, and then you normalized it, it becomes 1, 0, 0 and if you look for half of that vector it would be 0.5, 0, 0

    Whereas the solution you would be looking for is 0.1, 0, 0, in other words normalizing it will change the length of the vector .... so you won't be able to find the proportion of the points in between the 2 starting points.
     
  7. BPPHarv

    BPPHarv

    Joined:
    Jun 9, 2012
    Posts:
    318
    Zoom I think your conceptual problem arises from the fact that the OP is asking for a set distance from A in the direction of A-B not a percentage of the line. The code examples above assume the distance value (x), representing the distance along line to travel, is less than the distance to travel. The normalization is so you can compute an absolute distance of X along the line.

    Your example uses 0.5 to represent 1/2 the length of the line not a fixed distance to travel. In your case the actual length of the line from A->B is less than the 0.5 distance to travel. The returned point is still in the direction of A->B but it's not on the line between A and B.
    Basically your asking to travel 0.5 units along a line that is only 0.2 units long.

    Of course if you were looking for a percentage then you wouldn't want to normalize as your calculations are based on the actual length of the line.
    Code (csharp):
    1.  
    2.  
    3. Vector3 Lerp(Vector3 start, Vector3 end, float percent)
    4. {
    5.      return (start + percent*(end - start));
    6. }
    7.  
     
  8. ZoomDomain

    ZoomDomain

    Joined:
    Aug 30, 2012
    Posts:
    150
    Thanks, i understand.
     
  9. game-dev333

    game-dev333

    Joined:
    Jan 11, 2014
    Posts:
    7
    thanks for share! This helped me a lot
     
  10. moire76

    moire76

    Joined:
    Jan 20, 2016
    Posts:
    6
    Hi there, thanks for this topic!
    I know it's an old thread, but I have a question.
    I thought I fully understood the theory, as it does not seem to be very hard.
    First I made a simple try and it looked perfect.
    I put spheres at the three points in editor and they formed a line nicely.

    Then I made another try with some negative coordinates and it all messed up my mind. :)

    So if I do:

    Vector3 a = new Vector3(4,-9,16);
    Vector3 b = new Vector3(-4,8,-12);
    Vector3 c = a+((b-a).normalized*2f);

    This gives me c=(3.5255,-7.9917,14.3392);

    If I place 3 spheres in the editor in the location of these 3 points, they are not on the same line.
    Can you guys please point me in the direction how I should modify the formula to be valid for coordinates regardless of they are negative or positive.

    Thanks in advance for your help!
     
  11. kru

    kru

    Joined:
    Jan 19, 2013
    Posts:
    452
    You can use the utility method in Vector3 to handle this now: See https://docs.unity3d.com/ScriptReference/Vector3.Lerp.html

    If you're interested in understanding the theory behind it, and re-implementing the logic on your own, then keep going. I suggest using simpler numbers to start with. Place your spheres at (0,0,0), (10,0,0) and see what you get.
     
  12. moire76

    moire76

    Joined:
    Jan 20, 2016
    Posts:
    6
    Dear Kru,
    Thanks very much for your ultra fast reply!
    As I mentioned, simple numbers works flawlessly, they are totally follow the described behavior.
    I only experience difficulties, when I try it with coordinates including negative numbers.

    I'm also looking for a distance from one end of the AB vector and not a proportion/percentage so using Lerp with normalized vector gave the exact same results for coords with negative numbers.

    I think I need to create absolute values somehow, to correct the anomaly of negative coords, but I'm just not good enough in Math to find a solution so far.

    UPDATE: OK, I have just created a script that places the objects according to the formula, and it works totally fine, no matter if the numbers are negative or positive. I don't know what I made wrong earlier, but now it looks all fine.

    Sorry, it must have been my bad, I just messed up something. :)

    Here's my script just in case if anyone would try it:

    // create an empty gameobject, then create 2 spheres and a cube under it
    // attach this script to the empty gameobject and assign the 3 objects to public vars
    // I placed the gameobject at 0,0,0 and the camera at 0,0,-30

    using UnityEngine;
    using System.Collections;

    public class test:MonoBehaviour{

    public GameObjects1;
    public GameObjects2;
    public GameObjectcube;

    Vector3 a = new Vector3(4,-9,16);
    Vector3 b = new Vector3(-4,8,-12);
    Vector3 c;

    void Start() {
    s1.transform.localPosition=a;
    s2.transform.localPosition=b;
    c=a+((b-a).normalized*30);
    cube.transform.localPosition=c;
    }

    }
     
    Last edited: Jan 23, 2017
  13. AD110

    AD110

    Joined:
    Apr 8, 2015
    Posts:
    3
  14. AD110

    AD110

    Joined:
    Apr 8, 2015
    Posts:
    3

    Thanks for the algorithm
     
  15. unnanego

    unnanego

    Joined:
    May 8, 2018
    Posts:
    199
    Strangely, for me it only works without normalization, but I'm working with vertices, maybe that's the reason?
     
  16. Madgvox

    Madgvox

    Joined:
    Apr 13, 2014
    Posts:
    1,317
    If you don't normalize you're working with a percentage. If you do normalize, you're working with a unit distance.
     
    darylkimoto likes this.
  17. unnanego

    unnanego

    Joined:
    May 8, 2018
    Posts:
    199
    if I normalize, the x coordinate is set to 0,5 instead of 0.0, which is the middle between two vectors.
     
  18. Captaingerbear

    Captaingerbear

    Joined:
    Mar 6, 2013
    Posts:
    57
    An old thread, but I have an issue that seems adjacent to this. Finding arbitrary point P along the line (A,B) is no problem for me, but I want to use this to give my players a heads up for nearby points of interest that are not yet onscreen.

    Point A will always be the center of the screen, and point B will be location of the point of interest, often very far off screen. I need to find P where P is a point along (A,B) that is exactly N pixels away from the edge of the screen. I can translate world to screen points easily enough, I'm just not sure how to go about finding the point I want in the first place. Any conceptual or logical pointers would be appreciated.
     
  19. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,998
    The original Q is very simple. What you're asking is more complex and probably ins't a good piggyback.

    To simplify, you could consider the edges of the rectangle 10 pixels from the edge of the screen. Each angle corrosponds to one of those edges, at a certain x or y coord. Given the edge. the math is probably simpler than "point along the line" math.
     
  20. darylkimoto

    darylkimoto

    Joined:
    Mar 28, 2018
    Posts:
    2
    This just opened up a world of understanding to me. Thank you!
     
    Madgvox likes this.
  21. Rachan

    Rachan

    Joined:
    Dec 3, 2012
    Posts:
    781

    Thank you very much it work perfectly!!!