Drawing regular Polygon - geometry

A regular polygon with N vertices. The lower side of the polygon is parallel to x axis. Given two point (x1, y1) and (x2, y2) if we draw a line through these points then the line would be parallel to the x axis. That means the lower side of the polygon is given. How to find the other n - 2 points. Each point could have floating value but it is grantee that x1, y1, x2, y2 is integer.
As example if N = 5 and (x1, y1) = (0, 0) and (x2, y2) = (5, 0)
I have to find these remaining 3 points (6.545085, 4.755283), (2.500000, 7.694209), (-1.545085 4.755283)
I am trying with vector rotation, but can't figure out any solution. How can I calculate ?

Given points x1, y1, x2, y2, number N.
Middle point of this edge is
xm = (x1 + x2) / 2
ym = y1
The center of polygon has coordinates
xc = xm
yc = y1 + Abs(x1 - x2)/2 * Ctg(Pi/N)
Radius of circumcircle is (Edit: 0.5 coefficient was missed)
R = 0.5 * Abs(x1 - x2) / Sin(Pi/N)
Kth (k=3..N) vertice of polygon has coordinates
xk = xc + R * Cos(-Pi/2 + Pi/N + (k - 2) * 2 * Pi/ N)
yk = yc + R * Sin(-Pi/2 + Pi/N + (k - 2) * 2 * Pi/ N)

Related

How do I calculate the fourth vertex of a tetrahedron given the other three?

I want to calculate the fourth vertex of a regular tetrahedron. I have the coordinates
{0, 0, Sqrt[2/3] - 1/(2 Sqrt[6])}, {-(1/(2 Sqrt[3])), -(1/2), -(1/(2
Sqrt[6]))} and {-(1/(2 Sqrt[3])), 1/2, -(1/(2 Sqrt[6]))}
Can anybody please help?
Find the center of face
cx = (x1 + x2 + x3)/3 and similar for y,z
Get two edge vectors
e2x = x2 - x1
e2y = y2 - y1
e2z = z2 - z1
e3x = x3 - x1
e3y = y3 - y1
e3z = z3 - z1
Calculate edge len
elen = sqrt(e2x*e2x+e2y*e2y+e2z*e2z)
Calculate vector product to get normal to this face
nx = e2y*e3z - e2z*e3y
ny = e2z*e3x - e2x*e3z
nz = e2x*e3y - e2y*e3x
Make unit normal
nlen = sqrt(nx*nx+ny*ny+nz*nz)
nx = nx / nlen
...
Make normal of needed length (tetrahedron height)
lnx = nx * sqrt(2/3) * elen
...
Add this normal to the face center
x4 = cx +/- lnx
y4 = cy +/- lny
z4 = cz +/- lnz
+/- signs correspond to two possible positions of the fourth vertex

Issue with finding angle between 3 points in Python

I have 3 points p1(x1, y1), p2(x2, y2) and p3(x3, y3). I am trying to calculate angle (in anti-clockwise direction) between these 3 points. I am using following dot product method as provided in multiple blogs and SE sites (like this).
def angle_between(p1, p2, p3):
x1, y1 = p1
x2, y2 = p2
x3, y3 = p3
v21 = (x1 - x2, y1 - y2)
v23 = (x3 - x2, y3 - y2)
dot = v21[0] * v23[0] + v21[1] * v23[1]
det = v21[0] * v23[1] - v21[1] * v23[0]
theta = np.rad2deg(np.arctan2(det, dot))
print(theta)
It is giving me correct angle for any points which are not on the straight line. For example
p1 = (0, 0)
p2 = (1, 0)
p3 = (1, 1)
angle_between(p1, p2, p3) # Prints -90
angle_between(p3, p2, p1) # Prints +90
However, if points are on the straight line, it is giving me same answer
p1 = (0, 0)
p2 = (1, 0)
p3 = (2, 0)
angle_between(p1, p2, p3) # Prints +180
angle_between(p3, p2, p1) # Prints +180
Here I was expecting (p3, p2, p1) to give -180. What am I missing here? If the method I am using is not correct, can someone help me point towards the correct method?
I have tried to use direct cosine law (as given here) but it only provides me angle without any sense of direction of the angle.
Check out this solution. It always provides positive angles, measured in anti-clockwise direction:
from math import atan2, degrees
def angle_between(p1, p2, p3):
x1, y1 = p1
x2, y2 = p2
x3, y3 = p3
deg1 = (360 + degrees(atan2(x1 - x2, y1 - y2))) % 360
deg2 = (360 + degrees(atan2(x3 - x2, y3 - y2))) % 360
return deg2 - deg1 if deg1 <= deg2 else 360 - (deg1 - deg2)

How to find the third vertices of a triangle when lengths are unequal

I have two vertices of a triangle and the lengths are unequal. How to find the third vertex?
Translate all points so that P2 becomes the origin.
Then you solve
x² + y² = d2²
(x - x3)² + (y - y3)² = d3²
(mind the renumbering of d1).
By subtraction of the two equations,
(2x - x3).x3 + (2y - y3).y3 = d2² - d3²
which is a linear equation, of the form
a.x + b.y + c = 0
and in parametric form
x = x0 + b.t
y = y0 - a.t
where (x0, y0) is an arbitrary solution, for instance (- ac / (a² + b²), - bc / (a² + b²)).
Now solve the quadratic equation in t
(x0 + b.t)² + (y0 - a.t)² = d2²
which gives two solutions, and undo the initial translation.
function [vertex_1a, vertex_1b] = third_vertex(x2, y2, x3, y3, d1, d3)
d2 = sqrt((x3 - x2)^2 + (y3 - y2)^2); % distance between vertex 2 and 3
% Orthogonal projection of side 12 onto side 23, calculated unsing
% the Law of cosines:
k = (d2^2 + d1^2 - d3^2) / (2*d2);
% height from vertex 1 to side 23 calculated by Pythagoras' theorem:
h = sqrt(d1^2 - k^2);
% calculating the output: the coordinates of vertex 1, there are two solutions:
vertex_1a(1) = x2 + (k/d2)*(x3 - x2) - (h/d2)*(y3 - y2);
vertex_1a(2) = y2 + (k/d2)*(y3 - y2) + (h/d2)*(x3 - x2);
vertex_1b(1) = x2 + (k/d2)*(x3 - x2) + (h/d2)*(y3 - y2);
vertex_1b(2) = y2 + (k/d2)*(y3 - y2) - (h/d2)*(x3 - x2);
end

calculating parallel lines in a circle

I am calculating lines (2 sets of coordinates ) ( the purple and green-blue lines ) that are n perpendicular distance from an original line. (original line is pink ) ( distance is the green arrow )
How do I get the coordinates of the four new points?
I have the coordinates of the 2 original points and their angles. ( pink line )
I need it to work if the lines are vertical, or any other orientation.
Right now I am trying to calculate it by:
1. get new point n distance perpendicular to the two old points
2. find where the circle intersects the new line I have defined.
I feel like there is an easier way.
Similarly to #MBo's answer, let's assume that the center is (0,0) and that your initial two points are:
P0 = (x0, y0) and P1 = (x1, y1)
A point on the line P0P1 has the form:
(x, y) = c(x1 - x0, y1 - y0) + (x0, y0)
for some constant c.
Let (u, v) be the normal to the line P0P1:
(u, v) = (y1 - y0, x1 - x0) / sqrt((x1 - x0)^2 + (y1 - y0)^2)
A point on any of the lines parallel to P0P1 has the form:
(x, y) = c(x1 - x0, y1 - y0) + (x0, y0) +/- (u, v)* n {eq 1}
where n is the perpendicular distance between lines and c is a constant.
What remains here is to find the values of c such that (x,y) is on the circle. But these can be calculated by solving the following two quadratic equations:
(c(x1 - x0) + x0 +/- u*n)^2 + (c(y1 - y0) + y0 +/- v*n)^2 = r^2
where r is the radius. Note that these equations can be written as:
c^2(x1 - x0)^2 + 2c(x1 - x0)*(x0 +/- u*n) + (x0 +/- u*n)^2
+ c^2(y1 - y0)^2 + 2c(y1 - y0)*(y0 +/- v*n) + (y0 +/- v*n)^2 = r^2
or
A*c^2 + B*c + D = 0
where
A = (x1 - x0)^2 + (y1 - y0)^2
B = 2(x1 - x0)*(x0 +/- u*n) + 2(y1 - y0)*(y0 +/- v*n)
D = (x0 +/- u*n)^2 + (y0 +/- v*n)^2 - r^2
which are actually two quadratic equations one for each selection of the +/- signs. The 4 solutions of these two equations will give you the four values of c from which you will get the four points using {eq 1}
UPDATE
Here are the two quadratic equations (I've reused the letters A, B and C but they are different in each case):
A*c^2 + B*c + D = 0 {eq 2}
where
A = (x1 - x0)^2 + (y1 - y0)^2
B = 2(x1 - x0)*(x0 + u*n) + 2(y1 - y0)*(y0 + v*n)
D = (x0 + u*n)^2 + (y0 + v*n)^2 - r^2
A*c^2 + B*c + D = 0 {eq 3}
where
A = (x1 - x0)^2 + (y1 - y0)^2
B = 2(x1 - x0)*(x0 - u*n) + 2(y1 - y0)*(y0 - v*n)
D = (x0 - u*n)^2 + (y0 - v*n)^2 - r^2
Let's circle radius is R, circle center is (0,0) (if not, shift all coordinates to simplify math), first chord end is P0=(x0, y0), second chord end is P1=(x1,y1), unknown new chord end is P=(x,y).
Chord length L is
L = Sqrt((x1-x0)^2 + (y1-y0)^2)
Chord ends lie on the circle, so
x^2 + y^2 = R^2 {1}
Doubled area of triangle PP0P1 might be expressed as product of the base and height and through absolute value of cross product of two edge vectors, so
+/- L * n = (x-x0)*(y-y1)-(x-x1)*(y-y0) = {2}
x*y - x*y1 - x0*y + x0*y1 - x*y + x*y0 + x1*y - x1*y0 =
x * (y0-y1) + y * (x1-x0) + (x0*y1-x1*y0)
Solve system of equation {1} and {2}, find coordinates of new chord ends.
(Up to 4 points - two for +L*n case, two for -L*n case)
I cannot claim though that this method is simpler - {2} is essentially an equation of parallel line, and substitution in {1} is intersection with circle.

Line Segment Circle Intersection

I am trying to determine the point at which a line segment intersect a circle. For example, given any point between P0 and P3 (And also assuming that you know the radius), what is the easiest method to determine P3?
Generally,
find the angle between P0 and P1
draw a line at that angle from P0 at a distance r, which will give you P3
In pseudocode,
theta = atan2(P1.y-P0.y, P1.x-P0.x)
P3.x = P0.x + r * cos(theta)
P3.y = P0.y + r * sin(theta)
From the center of the circle and the radius you can write the equation describing the circle.
From the two points P0 and P1 you can write the equation describing the line.
So you have 2 equations in 2 unknowns, which you can solved through substitution.
Let (x0,y0) = coordinates of the point P0
And (x1,y1) = coordinates of the point P1
And r = the radius of the circle.
The equation for the circle is:
(x-x0)^2 + (y-y0)^2 = r^2
The equation for the line is:
(y-y0) = M(x-x0) // where M = (y1-y0)/(x1-x0)
Plugging the 2nd equation into the first gives:
(x-x0)^2*(1 + M^2) = r^2
x - x0 = r/sqrt(1+M^2)
Similarly you can find that
y - y0 = r/sqrt(1+1/M^2)
The point (x,y) is the intersection point between the line and the circle, (x,y) is your answer.
P3 = (x0 + r/sqrt(1+M^2), y0 + r/sqrt(1+1/M^2))
Go for this code..its save the time
private boolean circleLineIntersect(float x1, float y1, float x2, float y2, float cx, float cy, float cr ) {
float dx = x2 - x1;
float dy = y2 - y1;
float a = dx * dx + dy * dy;
float b = 2 * (dx * (x1 - cx) + dy * (y1 - cy));
float c = cx * cx + cy * cy;
c += x1 * x1 + y1 * y1;
c -= 2 * (cx * x1 + cy * y1);
c -= cr * cr;
float bb4ac = b * b - 4 * a * c;
// return false No collision
// return true Collision
return bb4ac >= 0;
}
You have a system of equations. The circle is defined by: x^2 + y^2 = r^2. The line is defined by y = y0 + [(y1 - y0) / (x1 - x0)]·(x - x0). Substitute the second into the first, you get x^2 + (y0 + [(y1 - y0) / (x1 - x0)]·(x - x0))^2 = r^2. Solve this and you'll get 0-2 values for x. Plug them back into either equation to get your values for y.
MATLAB CODE
function [ flag] = circleLineSegmentIntersection2(Ax, Ay, Bx, By, Cx, Cy, R)
% A and B are two end points of a line segment and C is the center of
the circle, % R is the radius of the circle. THis function compute
the closest point fron C to the segment % If the distance to the
closest point > R return 0 else 1
Dx = Bx-Ax;
Dy = By-Ay;
LAB = (Dx^2 + Dy^2);
t = ((Cx - Ax) * Dx + (Cy - Ay) * Dy) / LAB;
if t > 1
t=1;
elseif t<0
t=0;
end;
nearestX = Ax + t * Dx;
nearestY = Ay + t * Dy;
dist = sqrt( (nearestX-Cx)^2 + (nearestY-Cy)^2 );
if (dist > R )
flag=0;
else
flag=1;
end
end

Resources