-3

I am using Sourcepawn, can also understand java ,but I need just a tip, idea to work on

Image - 2 red dots are end points of the beam. Beam can be in any angles (X,Y). I need to focus on green dot, check the closest distance between orange line (I don't have any points more, just 2 ends) and green dot.

Any tips appreciated, thanks!

Carsten Massmann
  • 16,701
  • 2
  • 16
  • 39
bonk
  • 3
  • 4
  • 1
    The closest point will always be on a right angle to the line, that should help somehow – Bagel03 Aug 16 '20 at 15:55
  • I think that i have another idea how I should solve it. Simply I'll send another beam like first one from this point, and check distance between end points. – bonk Aug 16 '20 at 16:03

1 Answers1

0

Sketch: 3 points Given that you want to know the vector d with defined points p1, p2 and p3 you could do the following (vector variables are underlined):




Or, in a more code friendly notation (I am using JavaScript here) we represent vectors as arrays with x- and y-values:

const fromP1=(p,i)=>p-p1[i],   // subtract vector p1 from current vector
         dot=(a,b)=>a.reduce((v,p,i)=>v+p*b[i],0); // scalar product
// these are just arbitrary sample point values:
const p1=[1,5,0], p2=[6,2.5,0], p3=[2,2,0];

const a=p2.map(fromP1),         // vector from P1 to P2
  b=p3.map(fromP1),             // vector from P1 to P3
 fa=dot(a,b)/dot(a,a),          // scalar factor for vector a
  c=a.map(p=>p*fa),             // scale vector a by fa
  d=b.map((p,i)=>p-c[i]);       // vector d = vector b - vector c
  
  console.log("vector c:",c);
  console.log("vector d:",d)

As a little side note: This method works just as well for 3 (or even more!) dimensions. Simply add further components (=coordinate values) to (all of) the vector arrays. The vector functions will automatically work with all defined dimensions.

enter image description here

If you only want to know the scalar value of the minimum distance then things get a littlie easier:

const fromP1=(p,i)=>p-p1[i],    // subtract vector p1 from current vector
         dot=(a,b)=>a.reduce((v,p,i)=>v+p*b[i],0); // scalar product
                                // sample point values (3D):
const p1=[1,5,0], p2=[6,2.5,0], p3=[2,2,0];

const a=p2.map(fromP1),         // vector from P1 to P2
      b=p3.map(fromP1);         // vector from P1 to P3

const ab=dot(a,b);

console.log("distance:",Math.sqrt(dot(b,b) - ab*ab/dot(a,a)) );
Carsten Massmann
  • 16,701
  • 2
  • 16
  • 39
  • Impressive explaination. Thank you! I am in trouble with getting scalar for "c". My code now looks like this : `float a[3], b[3], c[3], d[3], fa, playerPos[3]; GetClientAbsOrigin(client, playerPos); playerPos[2] = tempBorder.fEndPoint1[2]; MakeVectorFromPoints(tempBorder.fEndPoint1, tempBorder.fEndPoint2, a); MakeVectorFromPoints(tempBorder.fEndPoint1, playerPos, b); // ? :() ScaleVector(a, fa);` Format has gone bad, I hope You could see this clearly. :P – bonk Aug 16 '20 at 19:37
  • Explaination : 1. playerPos is our P3. 2. tempBorder.fEndPoint1 is P1 (I am making both heights equals, because I am using X,Y,Z points) 3. I am making vectors for "a" and "b" 4. I am going to scale vector "a", but I don't have a scalar. I don't understand your javascript snippet, and probably I'll need to do it manually. Here's the API: https://sm.alliedmods.net/new-api/vector – bonk Aug 16 '20 at 19:47
  • The scale factor `fa` to calculate the vector `c` from `a` (for three dimensions) is: `(ax*bx + ay*by + az*bz)/(ax*ax + ay*ay + az*az)`. So `c=[ax*fa,ay*fa,az*fa]`. `.map()` and `reduce()` are merely parametric ways of doing the same. (You could use `GetVectorDotProduct()` for the dot-product.) – Carsten Massmann Aug 16 '20 at 20:20