0

I just can't seem to spot my bug here, can you?

bool oblong (vec2 p, vec2 a, vec2 b, float r) {
 return (((b.y-a.y)*(p.x-a.x)+(b.x-a.x)*(p.y-a.y))^2/((b.x-a.x)^2+(b.y-a.y)^2)<= r);
}

This is my second GLSL program, (my first was a circle.) Thanks for your input!

Jack
  • 2,229
  • 2
  • 23
  • 37

2 Answers2

7

You don't explain very well what the function is supposed to do and what your single-character variable names actually mean. I'm going to guess that a and b are the points on the line segment, and p is the point of interest. r must be some distance that the function tests against (generally, you should return the distance and let the user test against it. If they want to keep it, it's there prerogative).

I guess your real problem is that in neither C, C++, or GLSL is ^ the "raise to a power" operator.

In any case, a correct version of this function would be as follows:

float DistToLine(vec2 pt1, vec2 pt2, vec2 testPt)
{
  vec2 lineDir = pt2 - pt1;
  vec2 perpDir = vec2(lineDir.y, -lineDir.x);
  vec2 dirToPt1 = pt1 - testPt;
  return abs(dot(normalize(perpDir), dirToPt1));
}

Note that this code has not been tested. I'm just implementing the solution presented at the given site. This is implemented in vector notation with vector arithmetic. Note that I very rarely get the X and Y components (I only do it once to get the perpendicular).

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
3

distance between a point and a line

Suppose we have two points pt1, pt2 (for line) and one desired point pt3.

v1 = line vector (pt2-pt1)

v2 = vector between the first point of the line and the desired point pt3 (pt1-pt3)

v3 = perpendicular to the vector (swap v1.x, v1.y of v1, and multiply one of them to -1 to make v3)

h = distance between the pt3 and the line

dot(v2, v3) = |v2||v3|cos(theta + PI /2) ⟹ cos(theta + PI /2) = dot(v2, v3) / (|v2|| v3|) ⟹ sin(theta) = -dot (v2,v3) /(|v2||v3|) and h = |v2| . sin(theta)
⟹ h = dot(v2,v3) / |v3| = dot(v2,norm(v3))

Code in GLSL:

float dist(vec2 pt1, vec2 pt2, vec2 pt3)
{
   vec2 v1 = pt2 - pt1;
   vec2 v2 = pt1 - pt3;
   vec2 v3 = vec2(v1.y,-v1.x);
   return abs(dot(v2,normalize(v3)));
}

See also https://www.ck12.org/book/ck-12-college-precalculus/section/9.6/ for "projecting one vector on another vector" as the other method.