Determine if 3 points form a right angle

In summary, the conversation discusses finding a right angle between three points and determining a perpendicular point along a bezier curve to a target point. Suggestions for finding the right angle include using the dot product or calculating the distances between pairs of points. There is also a discussion about the notation and defining the bezier curve.
  • #1
abeall
21
0
Greetings, all!

This is really basic, but I'm a humble programmer, not a mathematician, and while working on a small script in which I need to determine a right angle, I realized that I don't really know what the best approach is.

Here's the abstract: I have 3 points, A,B,C, I want to determine if B forms a right angle between A and C. My only thought is to find the angle between A,B and B,C, arbitrarily subtract one from the other, and if the absolute value is 90 then we have a right angle.

Here's the full context: What I'm actually trying to do is, given a bezier curve defined as p1,cp1,cp2,p2 and another random point, pt, I want to find what point along the bezier curve is exactly perpendicular to the the target point(pt). Scary, huh? I have a function which I can use to walk the bezier curve at really small increments, finding points along the way, so eventually I'll find one point on the curve whose angle from previous point on the curve and angle to target point should form a right angle, or at least very close. The closest will be close enough, I hope.

Any help on the right angle is really what I need. Any better ideas on finding a perpendicular point along a bezier curve to a target point would be welcome, too.

Thanks!
- aaron
 
Mathematics news on Phys.org
  • #3
Why not just convert them to vectors and take the cross product?
 
  • #4
I would think the dot product would be better. You can determine whether or not two vectors are perpendicular with the cross product but that requires calculating the lengths of the vectors also. Two vectors are perpendicular if and only if the dot product is 0. Of course, since you don't know which two lines are supposed to be perpendicular, you would have check all three possible pairs of lines.

A more fundamental check would be to calculate squares of the three distances between pairs of points and see if they satisfy the Pythagorean theorem.
 
  • #5
HallsofIvy said:
I would think the dot product would be better. You can determine whether or not two vectors are perpendicular with the cross product but that requires calculating the lengths of the vectors also. Two vectors are perpendicular if and only if the dot product is 0. Of course, since you don't know which two lines are supposed to be perpendicular, you would have check all three possible pairs of lines.

A more fundamental check would be to calculate squares of the three distances between pairs of points and see if they satisfy the Pythagorean theorem.
I suggested the vector approach so if they weren’t right and he wanted them to be he could find a new point that would satisfy easily. Yup go with the dot product – don’t know what I was thinking!
 
  • #6
Thanks all.

These are in 2D. So, how would I determine the dot product of two 2D vectors, AB and BC?

I just looked up dot product and I'm having a hard time how I would convert it to programming language, I get quite lost in all the notation...
 
  • #7
Well, I don't know about the dot product or what it might have to offer, but it turns out this works:

90 - ( Math.abs(angle1) - Math.abs(angle2) )

The two angles I think are perpendicular if the sum of the above equation is 0.

I'm also looking for speed, though, and to obtain the two angles above requires the following function to be run twice:
function angle(p1,p2){
return -Math.atan2((p1.x-p2.x), (p1.y-p2.y))/(Math.PI/180);
}

This is a notable resource drain. If there was a more efficient way that avoided this, it would be better.
 
Last edited:
  • #8
abeall said:
...Here's the full context: What I'm actually trying to do is, given a bezier curve defined as p1,cp1,cp2,p2 and another random point, ...

What do you mean by that? How is the curve defined exactly?

abeall said:
... Any better ideas on finding a perpendicular point along a bezier curve to a target point would be welcome, too. ...

As long I can understand you have two points. One on the curve and the target point. Where is the 3rd point?

Do you mean that the line joining these two points is perpendicular to the tangent of the curve at the first point? (or I am lossing something? :smile: )
 
  • #9
Do you mean that the line joining these two points is perpendicular to the tangent of the curve at the first point?

Ah, yes, I'm pretty sure that's what I mean. The 3rd point to define the angle doesn't really exist...

At any rate, after further testing, the solution I posted above does not work. It breaks down in some situations.

An added challenge is that, since I'm walking the bezier curve and comparing the current tangent to the target point compared the previous, I also need to know when I've overstepped the curve. This way I can back up the previous point, and continue to walk at a smaller increment to refine the accuracy a few iterations.
 
Last edited:
  • #10
just so we're all on the same page, perhaps you clarify your bezier notation a bit.
are cp1 & cp2 the two non colocated points of a cubic curve as per wikipedia?
 
  • #11
Ok then!

Your curve must be something like that

[tex]\vec{r}(t)=(1-t)^3\,\vec{p}_o+3\,t\,(1-t)^2\,\vec{p}_1+3\,t^2\,(1-t)\,\vec{p}_2+t^3\,\vec{p}_3 [/tex]

where [tex]\vec{p}_o,\,\vec{p}_1,\,\vec{p}_2,\,\vec{p}_3 [/tex] are fixed.

Now the tangent to the curve is [tex]\dot{\vec{r}}(t)[/tex]
If the second point is [tex]\vec{p}=(x_o,y_o) [/tex] the vector joining the two poins (on the curve and the one off it) is

[tex]\vec{R}(t)=\vec{r}(t)-\vec{p} [/tex]

In order to find the point on the curve you have to solve the equation

[tex] \dot{\vec{r}}(t) \cdot \vec{R}(t)=0 [/tex]
 
  • #12
mda said:
just so we're all on the same page, perhaps you clarify your bezier notation a bit.
are cp1 & cp2 the two non colocated points of a cubic curve as per wikipedia?

This is the function I'm using to find a point on a cubic bezier, given a time/precent(0-1):
function getBezier(percent,p1,cp1,cp2,p2) {
function b1(t) { return t*t*t }
function b2(t) { return 3*t*t*(1-t) }
function b3(t) { return 3*t*(1-t)*(1-t) }
function b4(t) { return (1-t)*(1-t)*(1-t) }
var pos = {x:0,y:0};
pos.x = p1.x*b1(percent) + cp1.x*b2(percent) + cp2.x*b3(percent) + p2.x*b4(percent);
pos.y = p1.y*b1(percent) + cp1.y*b2(percent) + cp2.y*b3(percent) + p2.y*b4(percent);
return pos;
}
 
  • #13
Rainbow Child,

That looks good, I think... unfortunately, I really don't understand what it is doing. To give you a sense of my mathematical ignorance, I don't understand the following:

1) What does 'r' represent?
2) What does 't' represent?
3) What does the arrow above certain things mean?

Beyond that, I really don't know how I would solve anything you presented and translate it into computer code(in this case it is syntax being executed in a JavaScript interpreter, though not actually browser JavaScript...). For instance, how would I solve the last equation that you have = 0?

Sorry for my ignorance, but thanks for trying to help me out -- that's why I came here. :)
 
  • #14
abeall said:
This is the function I'm using to find a point on a cubic bezier, given a time/precent(0-1):
function getBezier(percent,p1,cp1,cp2,p2) {
function b1(t) { return t*t*t }
function b2(t) { return 3*t*t*(1-t) }
function b3(t) { return 3*t*(1-t)*(1-t) }
function b4(t) { return (1-t)*(1-t)*(1-t) }
var pos = {x:0,y:0};
pos.x = p1.x*b1(percent) + cp1.x*b2(percent) + cp2.x*b3(percent) + p2.x*b4(percent);
pos.y = p1.y*b1(percent) + cp1.y*b2(percent) + cp2.y*b3(percent) + p2.y*b4(percent);
return pos;
}

Ok! I will try to explain.

First of all [tex]\vec{r}(t)[/tex] represents your Bezier curve and it has an arrow above it because it stands for a vector , i.e. a point [tex](x,y)[/tex]. The [tex]t[/tex] is the variable belonging to the interval (0,1). In your code "time/precent(0-1)", right?

By ...programming skills have a maximum value of zero, but I will try to help.
As I can read your curve is

[tex]\vec{r}(t)=(1-t)^3\,\vec{p}_2+3\,t\,(1-t)^2\,\vec{cp}_2+3\,t^2\,(1-t)\,\vec{cp}_1+t^3\,\vec{p}_1 [/tex]

(forget the arrows, I have a problem with the correct formalism! :smile:)

Now the idea is to construct another "curve"

[tex]\dot{\vec{r}}(t)=-3\,t^2\,\vec{p}_2+(3-12\,t+9\,t^2)\,\vec{cp}_2+3\,t(2-3\,t)\,\vec{cp}_1+3\,t^2\,\vec{p}_1 [/tex]

exactly as you did for the Bezier curve.
Does it makes any sense until now?
 
Last edited:
  • #15
ok, another way to do this is to minimize the distance between pt and r, with respect to t.

You have to solve:
dx/dt (x-ptx) + dy/dt (y-pty) = 0.

This is a 6 term polynomial, so I would solve the entire problem using a linear algebra representation. That should be more efficient than testing the entire curve. The hardest part is finding the roots... the rest is straightforward.
 
  • #16
mda said:
ok, another way to do this is to minimize the distance between pt and r, with respect to t.

You have to solve:
dx/dt (x-ptx) + dy/dt (y-pty) = 0.

This is a 6 term polynomial, so I would solve the entire problem using a linear algebra representation. That should be more efficient than testing the entire curve. The hardest part is finding the roots... the rest is straightforward.

Sorry but that's exactly what

[tex] \dot{\vec{r}}(t) \cdot \vec{R}(t)=0 [/tex]

means! :smile:
 
  • #17
Rainbow Child said:
Sorry but that's exactly what

[tex] \dot{\vec{r}}(t) \cdot \vec{R}(t)=0 [/tex]

means! :smile:

sorry, didn't see your first post.
My main point was that linear algebra may be a convenient framework since the quintic is a bit messy and not that easy to solve.
 
  • #18
Thanks Rainbow Child and mda,

I think I might understand it a little better... I might be able to translate that last curve, the one you said "Now the idea is to construct another "curve"" about. However, what does that curve represent? What I'm really looking for is one point.

Here, take a look at this:
http://abeall.com/files/temp/perpendicular.gif

targetP is a fixed point. The red lines are my P tangents(if that's a proper use of the term tangent) in the form of an angle, in degrees(ie not a vector), which I can calculate already. I'm trying to find what point along the curve is "perpendicular" to that point -- ie its tangent most closely intersects targetP.

Now, not to dilute the issue, which at its core is determine "how perpendicular" Pn is to targetP, but there is an added challenge: what I'm doing is stepping through the curve at a small increment, and when I overstep the perpendicular point, I back up and step through at a smaller increment, and repeat the process several iterations to achieve adaptive accuracy. This means I need to not only know "how perpendicular" a point is to targetP, but I also need to know if I overstep.
 
Last edited:
  • #19
The red lines in your image are not tangents. Are they meant to be normals? What is it you're trying to find, anyway?
 
  • #20
The red lines in your image are not tangents. Are they meant to be normals?
Yeah, I guess they are normals, I don't know. Though in actuality, what I have is tangents/direction along line(technically, I'm finding the angle between a point and a previous point), and what is shown is 90 degrees from that to illustrate what I'm trying to find. I guess I need a layman's definition of tangent and normal in this context. But whatever they are called, that illustration shows them.

What is it you're trying to find, anyway?
In the illustration shown, I am trying to find Pn. The point which is "perpendicular" to targetP, I don't know any other way to say it.
 
Last edited:
  • #21
abeall said:
Thanks Rainbow Child and mda,
Now, not to dilute the issue, which at its core is determine "how perpendicular" Pn is to targetP, but there is an added challenge: what I'm doing is stepping through the curve at a small increment, and when I overstep the perpendicular point, I back up and step through at a smaller increment, and repeat the process several iterations to achieve adaptive accuracy. This means I need to not only know "how perpendicular" a point is to targetP, but I also need to know if I overstep.

abeall, there's a number of different 'root-finding algorithm' of varying complexity to do what you want. Try searching on wiki... the classic ones are bisection, secant and Newton. There's a tradeoff between accuracy and complexity, so I would suggest starting with the simplest one (bisection).

A lot of them essentially require that you keep track of the last function evaluation (your last value of R.r') which provides the info you need. If the sign has changed, you have overshot so you know you have 'bracketed' the root between your last value of t and the new one. The more complex methods take advantage of the slope (and higher order derivates) to guess the best place to check next, but that means more function evaluations so the speedup is limited.
 
Last edited:
  • #22
After some research and experimentation, it appears that I can determine the point on the curve whose normal intersects the targetP quite easily: by finding the closest point! It's pretty obvious from looking at my illustration, but it also proved true in every other curve form I could come up with. The closest point on the curve to the targetP was also "perpendicular" as I wanted it.

So I'm now walking down the curve, comparing distance from current P to targetP(determined as p1^2 + p2^2 without taking the square root, because that's a slow operation in computing and unnecessary for comparison) compared to previous distance. When the distance begins to rise, I know I've overstepped, I back up and refine. Seems to be working.
 
  • #23
Thanks mda, that's interesting. I'm looking into the bisection method...
 
  • #24
Also, in case you haven't realized, since the equation is quintic there's as many as five points on the line that satisfy the equation. (They aren't all equally close however; R will tell you that.) This means that if you use bisection you may run into problems where the sign changes an even number of times. But try it and find out
 
Last edited:
  • #25
abeall said:
After some research and experimentation, it appears that I can determine the point on the curve whose normal intersects the targetP quite easily: by finding the closest point!

Yes that will work too... now you are minimising |R| which is essentially the same as root-finding on its derivative. The connection between these two is that R'=r' since pt is fixed. You are determining the sign of the derivative by keeping track of the last function evaluation.

The root-finding algorithms can of course be adapted to minimisation... by taking the derivative (which can also be done numerically for smooth curves).
 

1. How do you determine if 3 points form a right angle?

To determine if 3 points form a right angle, you can use the Pythagorean theorem or the dot product formula. The Pythagorean theorem states that in a right triangle, the square of the length of the hypotenuse is equal to the sum of the squares of the other two sides. The dot product formula states that if the dot product of two vectors is equal to 0, then the two vectors are perpendicular and form a right angle.

2. Can any three points form a right angle?

No, not all three points can form a right angle. For three points to form a right angle, they must be arranged in a specific way. Two of the points must be on the sides of the right angle and the third point must be on the vertex of the right angle.

3. What if the points are not in a straight line?

If the points are not in a straight line, then they cannot form a right angle. In order for three points to form a right angle, they must be arranged in a way that creates a 90-degree angle at one of the points.

4. Are there any other ways to determine if three points form a right angle?

Yes, besides using the Pythagorean theorem or the dot product formula, you can also use the slope formula. If the slope of one of the lines formed by the three points is the negative reciprocal of the slope of the other line, then the lines are perpendicular and the points form a right angle.

5. What are some real-life applications of determining if three points form a right angle?

Determining if three points form a right angle is useful in many fields, such as architecture, engineering, and surveying. It is important in these fields to accurately measure and construct right angles in order to create stable and precise structures. It is also used in computer graphics to create 3D models and animations. Additionally, it is used in navigation and mapping to determine the direction of travel and distances between points.

Similar threads

Replies
8
Views
1K
Replies
3
Views
1K
Replies
1
Views
3K
  • General Math
Replies
1
Views
715
Replies
1
Views
766
Replies
8
Views
3K
  • General Math
Replies
4
Views
1K
Replies
1
Views
1K
Back
Top