How to know when a vector changes direction suddently? - math

I have a polygon where I'm looking for 2 segments that are approximately 90 degree (+-20°). I always found the first one which is between p1 and p2 and I want to find p3, but in the image below, we can se that between p3 and p2 it's not a direct line.
I had thought maybe looking not directly the first point after p2 but a certain number of points and to see if it's still 90° between p1 p2 and that point but then I have the problem that it will not stop to the good p3. So I thought maybe a cost function calculated with the distance between p2 and the looking point and maybe the dot product, but it didn't turned out to be good.
Does someone maybe have an idea how could I just ignore the points between p3 and p2?

You could try to adapt the Hough transform to this application.

Related

How to find two points along an existing line

I'm sure this is basic trigonometry, and I bet I covered at school many years ago, but I struggle knowing what function to apply to a real world situation. Anyway, rather than try and explain what I need help with, I've drawn a little diagram:
I know p1, p2, r1 and r2 but I can't remember (or know how to search for) how to work out what p3 and p4 are.
The basic application of this setup is I have 2 circles (red and blue) and I need them constantly connected as I drag them around the canvas. The pink link will connect them via their centre points but I don't want the line to penetrate the circle's circumferences.
Hope that makes sense? Thanks in advance.
this is simple vector math (no trigonometry needed)
create unit vector v with P1 to P2 direction
That is easy in vector form:
v=P2-P1; v/=|v|
And when put into 2D:
v.x=P2.x-P1.x;
v.y=P2.y-P1.y;
l=sqrt((v.x*v.x)+(v.y*v.y))
v.x/=l;
v.y/=l;
Now just translate from P1,P2by r1,r2
Vector form:
P3=P1+r1*v
P4=P2-r2*v
In 2D:
P3.x=P1.x+r1*v.x;
P3.y=P1.y+r1*v.y;
P4.x=P2.x-r2*v.x;
P4.y=P2.y-r2*v.y;
You have to solve the following equation system:
For p3 -->
(X-p1x)/(p1x-p2x)=(Y-p1y)/(p1y-p2y)
(X-p1x)^2 + (Y-p1y)^2 = r1^2
The same for p4 just change r1 for r2 and p1 for p4 in the second equation.
The first equation is the equation of a line given 2 points.
And the second equation is the equation of a circle given a center point and a radius.
The resulting X, Y values will be the values of p3, and then p4.
Let d be the distance between p1(x1, y1) and p2(x2,y2)
Thus
d = sqrt((x1-x2)^2 + (y1-y2)^2)
Now point p3(x3, y3) divides the line between p1 and p2 in the ratio of r1:(d-r1)
Thus
x3 = (r1*x2 + (d-r1)*x1)/d and
y3 = (r1*y2 + (d-r1)*y1)/d
Similarly for p4(x4, y4)
x4 = (r2*x1 + (d-r2)*x2)/d and
y4 = (r2*y1 + (d-r2)*y2)/d
What I am going to say is a little long. I will let you write your own code, however, of course will not help with that.
You know points P1, P2, and radius R1 and R2. Say suppose points P1 and P2 have coordinates (x1,y1) and (x2,y2) respectively.
The line connecting P1 and P2 is a straight line and hence you can calculate the slope of the line using the formula m=(y2-y1)/(x2-x1). Since you know the slope and know two coordinates, you can calculate the intercept c and construct a formula of the form y=mx+c.
Once the line formula is there, you can apply values for x and calculate y for point P3, lets say x3 and y3 since you have the radius R1. Similarly, calculate the coordinates for P4.

R Find the point of intersection of two lines connecting 4 coordinates

I apologize in advance if my code looks very amateurish.
I'm trying to assign quadrants to 4 measurement stations approximately located on the edges of a town.
I have the coordinates of these 4 stations:
a <- c(13.2975,52.6556)
b <- c(14.0083,52.5583)
c <- c(13.3722,52.3997)
d <- c(12.7417,52.6917)
Now my idea was to create lines connecting the north-south and east-west stations:
line.1 <- matrix(c(d[1],b[1],d[2],b[2]),ncol=2)
line.2 <- matrix(c(a[1],c[1],a[2],c[2]),ncol=2)
Plotting all the stations the connecting lines looks allright, however not very helpful for analyzing it on a computer.
So I calculated the eucledian vectors for the two lines:
vec.1 <- as.vector(c((b[1]-d[1]),(b[2]-d[2])))
vec.2 <- as.vector(c((c[1]-a[1]),(c[2]-a[2])))
which allowed me to calculate the angle between the two lines in degrees:
alpha <- acos((vec.1%*%vec.2) / (sqrt(vec.1[1]^2+vec.1[2]^2)*
sqrt(vec.2[1]^2+vec.2[2]^2)))) * 180/pi
The angle I get for alpha is 67.7146°. This looks fairly good. From this angle I can easily calculate the other 3 angles of the intersection, however I need values relative to the grid so I can assign values from 0°-360° for the wind directions.
Now my next planned step was to find the point where the two lines intersect, add a horizontal and vertical abline through that point and then calculate the angle relative to the grid. However I can't find a proper example that does that and I don't think I have a nice linear equation system I could solve.
Is my code way off? Or maybe anyone knows of a package which could help me? It feels like my whole approach is a bit wrong.
Okay I managed to calculate the intersection point, using line equations. Here is how.
The basic equation for two points is like this:
y - y_1 = (y_2-y_1/x_2-x_1) * (x-x_1)
If you make one for each of the two lines, you can just substitute the fractions.
k.1 <- ((c[2]-a[2])/(c[1]-a[1]))
k.2 <- ((b[2]-d[2])/(b[1]-d[1]))
Reshaping the two functions you get a final form for y:
y <- (((-k.1/k.2)*d[2]+k.1*d[1]-k.1*c[1]+d[2])/(1-k.1/k.2))
This one you can now use to calculate the x-value:
x <- ((y-d[2])+d[1]*k.2)/k.2
In my case I get
y = 52.62319
x = 13.3922
I'm starting to really enjoy this program!
Wikipedia has a good article on finding the intersection between two line segments with an explicit formula. However, you don't need to know the point of intersection to calculate the angle to the grid (or axes of coordinate system.) Just compute the angles from your vec.1 and vec.2 to the basis vectors:
e1 <- c(1, 0)
e2 <- c(0, 1)
as you have done.

Tangent circle(s) for two other circles?

There are two circles: a centered at point A, and circle b (center at B). What is the equation to calculate 2D position of all or none tangent circles possible. Main constraint is, that radius is the same for all the circles. As far as I know, there should be either no solution (figure 2), or 2 solutions (figure 1). How to find out if there are solutions, and also position of centers of those solutions (C and D).
Figure 1: 2 solutions should be possible here
Figure 2: No solutions!
Update (solution):
1) Calculate distance from A to B -> |AB|:
2) Checks whether a solution exist, it exist only if:
3) If it exist, calculate half-point between points A and B:
4) Create normalized perpendicular vector to line segment AB:
5) Calculate distance from this H point to C point -> |HC|:
6) Finally calculate point C along the (HC) starting at X at distance |HC|:
I suppose this question should migrate to a more math related site.
Try to imagine where these two tangent circles go when the circles a and b get further and further apart. They get closer to the line AB. Once the AB segment equals 4r these two tangent circles will overlap. From now on, once circles a and b get further apart, there's no tangent circles whatsoever.
If you want to calculate the position of these circles, just assume that the distance between the centers is always 2r:
You should get two, one or none solutions for xC and yC, which will be the centers of your tangent circles. I hope I haven't messed something up.
Solutions
Provided you do know there are solutions ( just check if d(A,B) <= 4r ), these are the coordinates of your two circles:
http://pastebin.com/LeW7Ws98
A little scary, eh? But it's working. There are the following variables:
x_A, y_A - the coordinates of the circle A,
x_B, y_B - the coordinates of the circle B,
r - the radius.
I've checked the solutions with the values from one of my comments below. I think that you can copy these solutions and inject them into your code straight away (provided there's a sqrt function) and get the results after declaring some variables.
These solutions are loosely derived from the Save's proposition but I couldn't comment below his answer - I've got less than 50 reputation points, duh ... ( thanks SO! You're the man! ). However I'm pretty sure they should be valid for my system anyways. Cheers
A solution exists iff d(A,B) = sqrt(2)*2*r
To find the center of the solution circles, that will let you draw the circonferences, you can intersect the circle with center (x_m,y_m), that is the medium point of the segment AB, of radius sqrt(2)*r, with the line perpendicular to AB and passing from (x_m,y_m)
This should give you all the needed information to check if a solution exixsts, and if it does, to draw it.

Direction of two points

Some high school math concept has been forgotten, so I ask here.
If I have two points p1(x1,y1), p2(x2,y2), the direction is P1-->p2, that's p1 points to p2. To represent this direction by vector, is it Vector(x2-x1,y2-y1) or Vector(x1-x2, y1-y2)?
By the way, what is the purpose to normalize a vector?
Answer 1: it is Vector(x2-x1,y2-y1)
Answer 2: Normalizing means to scale the vector so that its length is 1. It is a useful operation in many computations, for example, normal vectors should be specified normalized for lighting calculations in computer graphics. The normalized vector of v(x,y) is vn(x/Length(v), y/length(v)).
HTH
A nice way to remember which way the subtraction goes is to think of what the vector actually does. Imagine vector v resting at p1, pointing and connecting to p2. This means that p1 + v = p2. Therefore, v = p2-p1.

Calculating the perpendicular plane to a triangle in 3D space

I have a triangle in 3D space defined by its 3 vertices, p0, p1, and p2.
I wish to calculate a plane in this 3D space which lies along both p0 and p1 and faces a third point, p2.
This plane is to be defined by a position and normalised direction/
In addition to lying along p0 and p1, and facing p2, the plane should also be perpendicular to the plane created by p0, p1, and p2
I've struggled with this for quite a while and any help anyone can offer is greatly appreciated.
Your question is ill-posed. For any plane that lies on p0 and p1 there will be some point on that plane that "faces" point p2. So all that's left to compute is some plane along p0 and p1.
normal = normalize(cross(p1-p0, pX-p0)) //pX is anything except p1
planePoint = p0
EDIT: see comments
here is an example of my comment explanation
octave:14> p0
p0 =
0 0 0
octave:15> p1
p1 =
0 0 5
octave:16> p2
p2 =
5 0 0
octave:17> cross(p1-p0, cross(p1-p0,p2-p0))
ans =
-125 0 0
You'll notice that the sign is wrong, play with the order of parameters in the cross product to get it facing the right way. Also don't forget to normalize...but it wont affect the direction. Also check to make sure the norm after each cross product isn't near 0, otherwise there is no unique answer.. (triangle forms a line)
Unless I'm misunderstanding what you're asking, a vector from the line to p2 will be the normal to the plane you're trying to define. Basically, you construct a line at right angles to the line p0-p1, running through p2.

Resources