Drawing a triangle in a coordinate plane given its three sides - math

The length of three sides of the triangle, a, b and c will be given, and I need to find the coordinates of the vertices. The center (probably the circumcenter) can either be the origin or (x,y).
Can anyone point me in the right direction?

I've read brainjam's answer and checked whether his answer is true and he is right.
Calculation:
O(0;0), A(a;0) and B(x;y) are the three points of the triangle. C1 is the circle around A and r1 = c; C2 is the circle around O and r2 = b. B(X;Y) is the intersection of C1 and C2, which means that the point is on both of the circles.
C1: (x - a) * (x - a) + y * y = c * c
C2: x * x + y * y = b * b
y * y = b * b - x * x
(x - a) * (x - a) + b * b - x * x = c * c
x * x - 2 * a * x + a * a + b * b - x * x - c * c = 0
2 * a * x = (a * a + b * b - c * c)
x = (a * a + b * b - c * c) / (2 * a)
y * y = b * b - ((a * a + b * b - c * c) / (2 * a)) * ((a * a + b * b - c * c) / (2 * a))
y = +- sqrt(b * b - ((a * a + b * b - c * c) / (2 * a)) * ((a * a + b * b - c * c) / (2 * a)))

Place the first vertex at the origin (0,0). Place the second vertex at (a,0). To compute the third vertex, find the intersection of the two circles with centers (0,0) and (a,0) and radii b and c.
Update: Lajos Arpad has given the details of computing the location of the third point in this answer. It boils down to (x,y) where x = (b2+a2-c2)/2a and y=±sqrt(b2-x2)

This question and the answers helped me out today in implementing this. It will calculate the unknown vertices, "c" of circle intersections given 2 known points (a, b) and the distances (ac_length, bc_length) to the 3rd unknown vertex, "c".
Here is my resulting python implementation for anyone interested.
I also referenced the following:
http://mathworld.wolfram.com/RadicalLine.html
http://mathworld.wolfram.com/Circle-CircleIntersection.html
Using django's geos module for the Point() object, which could be replaced with shapely, or point objects removed altogether really.
from math import sqrt
from django.contrib.gis.geos import Point
class CirclesSeparate(BaseException):
pass
class CircleContained(BaseException):
pass
def discover_location(point_a, point_b, ac_length, bc_length):
"""
Find point_c given:
point_a
point_b
ac_length
bc_length
point_d == point at which the right-angle to c is formed.
"""
ab_length = point_a.distance(point_b)
if ab_length > (ac_length + bc_length):
raise CirclesSeparate("Given points do not intersect!")
elif ab_length < abs(ac_length - bc_length):
raise CircleContained("The circle of the points do not intersect")
# get the length to the vertex of the right triangle formed,
# by the intersection formed by circles a and b
ad_length = (ab_length**2 + ac_length**2 - bc_length**2)/(2.0 * ab_length)
# get the height of the line at a right angle from a_length
h = sqrt(abs(ac_length**2 - ad_length**2))
# Calculate the mid point (point_d), needed to calculate point_c(1|2)
d_x = point_a.x + ad_length * (point_b.x - point_a.x)/ab_length
d_y = point_a.y + ad_length * (point_b.y - point_a.y)/ab_length
point_d = Point(d_x, d_y)
# get point_c location
# --> get x
c_x1 = point_d.x + h * (point_b.y - point_a.y)/ab_length
c_x2 = point_d.x - h * (point_b.y - point_a.y)/ab_length
# --> get y
c_y1 = point_d.y - h * (point_b.x - point_a.x)/ab_length
c_y2 = point_d.y + h * (point_b.x - point_a.x)/ab_length
point_c1 = Point(c_x1, c_y1)
point_c2 = Point(c_x2, c_y2)
return point_c1, point_c2

When drawing an unknown triangle, it's usually easiest to pick one side (say, the longest) and place it horizontally or vertically. The endpoints of that side make up two of the triangle's vertices, and you can calculate the third by subdividing the triangle into two right triangles (the other two sides are the hypotenuses) and using the inverse sine/cosine functions to figure out the missing angles. By subdividing into right triangles, I mean something that looks like the image here: http://en.wikipedia.org/wiki/File:Triangle.TrigArea.svg Your first side would be AC in that drawing.
Once you have the triangle figured out, it should be easy to calculate it's center and translate it so that it is centered on whatever arbitrary center point you like.

First check the that the triangle is possible:
a+b >= c
b+c >= a
c+a >= b
Then, if it is, solve for the intersection of the two circles. The basic vertices are
{0,0}, {a,0}, {x,y}
where
x = (a^2-b^2+c^2)/(2a)
y = sqrt(c^2-x^2)
Finding the circumcenter is pretty easy from this point.

Related

Find the position of a point on a circle so it has a given distance to a point on another circle

I have a point on a half circle that needs a line connecting it to the black half circle. The line goes through the origin of the orange circle (perpendicular). When moving along the upper circle, the length of the line changes. Is there a way to calculate a position for the arrow, so the green line has a length of a given value? None of the circles are necessarily at the origin.
No need to check if the green line does intersect the black circle, I already made sure that's the case.
For the length s of the line from the orange centre to the black circle you get the formula:
s^2 = (x + r * cos(a))^2 + (y + r * sin(a))^2
where x is the absolute value of the x-component of the centre of the black circle and y the corresponding y-component. r is the radius of the black circle. a is the angle of the intersection point on the black circle (normally there will be two solutions).
Expanding the given formula leads to:
s^2 = x * x + r * r * cos(a)^2 + 2* r * x * cos(a)
+ y * y + r * r * sin(a)^2 +2 *r * y * sin(a)
As
r * r * cos(a)^2 + r * r * sin(a)^2 = r * r
we have
s^2 - x^2 - y^2 - r^2 = 2 *r * (x * cos(a) + y * sin(a)) (1)
Dividing by 2*r and renaming the left side of the equation p (p contains known values only) results in
p = x * cos(a) + y * sin(a) = SQRT(x * x + y * y) * sin(a + atan(x / y))
==>
a = asin(p /SQRT(x*x + y*y)) + atan(x / y) (2)
Let's have an example with approximate values taken from your drawing:
x = 5
y = -8
r = 4
s = 12
Then (1) will be
144 = 25 + 16 + 64 + 8 * (5 * cos(a) - 8 * sin(a)) ==>
39 / 8 = 5 * cos(a) - 8 * sin(a) =
SQRT(25 + 64) * sin(a + atan(5 / -8)) ==>
0.5167 = sin(a + atan(5 / -8))
asin(0.5167) = a - 212°
asin(0.5167) has two values, the first one is 31.11°, the second one is 148.89°. This leads to the two solutions for a:
a1 = 243.11°
a2 = 360.89° or taking this value modulo 360° ==> 0.89°
I just found a much simpler solution using the Law of cosines:
c * c = a * a + b * b - 2ab * cos(gamma)
You got a triangle defined by three points: the centre points of both circles and the point of intersection on the black circle. The lengths of all three sides are known.
So we get:
cos(gamma) = (a * a + b * b - c * c) / 2ab
If we choose the angle at centre of orange circle to be gamma we get
a = sqrt(89) = 9.434 (distance between the centres of both circles)
b = 12 (distance between centre of orange circle and point if intersection
c = 4 (radius of black circle)
Using this values we get:
cos(gamma) = (89 + 144 - 16) / (2 * sqrt(89) * 12) = 0.9584
gamma = acos(0.9584) = +/- 16.581°
´

Minimum distance between two circles along a specified vector on a cartesian plane

I am trying to solve the following problem (I am using Matlab, though pseudo-code / solutions in other languages are welcome):
I have two circles on a Cartesian plane defined by their centroids (p1, p2) and their radii (r1, r2). circle 1 (c1 = [p1 r1]) is considered 'dynamic': it is being translated along the vector V = [0 -1]. circle 2 (c2 = [p2 r2]) is considered 'static': it lies in the path of c1 but the x component of its centroid is offset from the x component of c2 (otherwise the solution would be trivial: the distance between the circle centroids minus the sum of their radii).
I am trying to locate the distance (d) along V at which circle 1 will 'collide' with circle 2 (see the linked image). I am sure that I can solve this iteratively (i.e. translate c1 to the bounding box of c2 then converge / test for intersection). However, I would like to know if there is a closed form solution to this problem.
Shift coordinates to simplify expressions
px = p1.x - p2.x
py = p1.y - p2.y
And solve quadratic equation for d (zero, one, or two solutions)
px^2 + (py - d)^2 = (r1 + r2)^2
(py - d)^2 = (r1 + r2)^2 - px^2
d = py +/- Sqrt((r1 + r2)^2 - px^2)
That's all.
As the question title does not match the question and accepted answer which is dependent on a fixed vector {0, -1}, or {0, 1} rather than an arbitrary vector I have added another solution that works for any unit vector.
Where (See diagram 1)
dx, dy is the unit vector of travel for circle c1
p1, p2 the centers of the moving circle c1 and static circle c2
r1, r2 the radius of each circle
The following will set d to the distance c1 must travel along dx, dy to collide with c2 if no collision the d will be set to Infinity
There are three cases when there is no solution
The moving circle is moving away from the static circle. u < 0
The moving circle never gets close enough to collide. dSq > rSq
The two circles are already overlapping. u < 0 luckily the math makes
this the same condition as moving away.
Note that if you ignore the sign of u (1 and 3) then d will be the distance to first (causal) contact going backward in time
Thus the pseudo code to find d
d = Infinity
rSq = (r1 + r2) ^ 2
u = (p1.x - p2.x) * dx + (p1.x - p2.x) * dy
if u >= 0
dSq = ((p2.x + dx * u) - p1.x) ^ 2 + ((p2.y + dy * u) - p1.y) ^ 2
if dSq <= rSq
d = u - (rSq - dSq) ^ 0.5
The point of contact can be found with
cpx = p1.x + dx * d;
cpy = p1.x + dy * d;
Diagram 1

Get vertex value that shapes 90 degrees with triangle centroid

I have this triangle:
I'm trying to get the vertex value highlighted in the green circle in order to draw that red line. Is there any equation that I can use to extract that value?
The centroid vertex G = (x=5.5, y=1.5)
The other vertex B = (x=0, y=1)
and the last vertex C = (x=7, y=0)
Any help would be appreciated. I know it might be a 5th grade math but I can't think of a way to calculate this point.
If you throw away the majority of the triangle and just keep the vector B->G and the vector B->C then this problem shows itself to be a "vector projection" problem.
These are solved analytically using the dot product of the 2 vectors and are well documented elsewhere.
Took me 2 days to figure this out, you basically need to get the slopes for the base vector and the altitude vector (centroid), then solve this equation: y = m * x + b for both vectors (the base + altitude). Then you'll get 2 different equations that you need to use substitution to get the x first then apply that value to the 2nd equation to get the y. For more information watch this youtube tutorial:
https://www.youtube.com/watch?v=VuEbWkF5lcM
Here's the solution in PHP (pseudo) if anyone is interested:
//slope of base
$m1 = getSlope(baseVector);
//slope of altitude (invert and divide it by 1)
$m2 = 1/-$m1;
//points
$x1 = $baseVector->x;
$y1 = $baseVector->y;
//Centroid vertex
$x2 = $center['x'];
$y2 = $center['y'];
//altitude equation: y = m * x + b
//eq1: y1 = (m1 * x1) + b1 then find b1
$b1 = -($m1 * $x1) + $y1;
//equation: y = ($m1 * x) + $b1
//eq2: y2 = (m2 * x2) + b2 then find b2
$b2 = -($m2 * $x2) + $y2;
//equation: y = ($m2 * x) + $b2;
//substitute eq1 into eq2 and find x
//merge the equations (move the Xs to the left side and numbers on the right side)
$Xs = $m1 - $m2; //left side (number of Xs)
$Bs = $b2 - $b1; //right side
$x = $Bs / $Xs; //get x number
$y = ($m2 * $x) + $b2; //get y number

Find line that is tangent to 2 given circles

I've got a situation in which I have 2 circles (C1 and C2)
and i need to find the line equation for the line that is tangent to both of these circles.
So as far as i'm aware, given a single point (P1) and C2's point and radius it is possible to quite easily get 2 possible points of tangency for C2 and P1 to make 2 line equations. But as i don't have P1, only the knowledge that the point will be one of a possible 2 points on C1, i'm not sure how to calculate this.
I assume it will be something along the lines of getting the 2 tangent line equations of C1 that are equal to the same of C2.
Both circles can have any radius, they could be the same or they could be hugely different. They will also never overlap (they can still touch though). And I'm looking for the 2 possible internal tangents.
Oh, and also, visuals would be very helpful haha :)
Let O be the intersection point between the line through the centers and the tangent.
Let d be the distance between the centers and h1, h2 be the distances between O and the centers. By similarity, these are proportional to the radii.
Hence,
h1 / h2 = r1 / r2 = m,
h1 + h2 = d,
giving
h1 = m d / (1 + m),
h2 = d / (1 + m).
Then the coordinates of O are found by interpolating between the centers
xo = (h2.x1 + h1.x2) / d
yo = (h2.y1 + h1.y2) / d
and the angle of the tangent is that of the line through the centers plus or minus the angle between this line and the tangent,
a = arctan((y2 - y1)/(x2 - x1)) +/- arcsin(r1 / h1).
You can write the implicit equation of the tangent as
cos(a).y - sin(a).x = cos(a).yo - sin(a).xo.
(source: imag.fr)
So we are going to use a homothetic transformation. If the circles C and C' have respectively centres O and O', and radius r and r', then we know there exists a unique homothetic transformation with centre J and ratio a, such that :
a = |JO|/|JO'| = r/r'
Noting AB is the vector from A to B, and |z| the norm of a vector z.
Hence you get J, knowing that it is between O and O' which we both already know.
Then with u the projection of JR on JO', and v the decomposition on its orthogonal, and considering the sine s and cosine c of the angle formed by O'JR, we have
|u| = |JR| * c
|v| = |JR| * s
c^2 + s^2 = 1
And finally because the triangle JRO' is right-angled in R :
s = r' / |JO|'
Putting all of this together, we get :
J = O + OO' / |OO'| * a / (a+1)
if |OJ| == r and |O'J| == r' then
return the orthogonal line to (OO') passing through J
|JR| = √( |JO'|^ - r'^2 )
s = r' / |JO'|
c = √( 1 - s^2 )
u = c * |JR| * OO' / |OO'|
w = (-u.y, u.x) % any orthogonal vector to u
v = s * |JR| * w / |w|
return lines corresponding to parametric equations J+t*(u+v) and J+t*(u-v)

computing tangent and bitangent vectors via partial derivatives

I'm trying to implement a simple water simulation, with theory from GPU Gems 1 chapter 1.
if you imagine a 3D plane (flat in the xz plane, with y denoting height at any point), the height field function is given as:
where:
Wavelength (w): the crest-to-crest distance between waves in world space.
Amplitude (A): the height from the water plane to the wave crest.
Speed (S): the distance the crest moves forward per second.
Direction (D): the horizontal vector perpendicular to the wave front along which the
crest travels.
This is straightforward to implement.
Please note the article in GPUGems uses the z direction for height, but this isn't standard for graphics (normally, x is width, y is height, z is depth). So I'll refer to the xz direction meaning the flat/horizontal plane directions.
So, having computed the height (y) value at any given point, I need to compute the bitangent and tangent vectors to that point, in order that I can compute a normal vector, which I need for lighting equations.
The bitangent and tangent vectors are partial derivatives in the x and z directions (y is the heightfield value).
So my question is, how can I take a partial derivative in the x and then the z directions for the height field function?
The article says that the partial derivative for the x direction is given by
I understand the concept of taking a partial derivative from this video:, but I don't know how to take the partial derivative of my heightfield function.
Can someone explain it (like I'm 5) - My grasp of maths isn't great!
You want to derive the following equation:
W(x) = A * sin(w * (D.x * x + D.y * z) + t * phi)
= A * sin(w * D.x * x + w * D.y * z + t * phi)
which is the above formula with the expanded dot product. Because we want to find the derivative with respect to x, all other variables (except x) are considered constant. So we can substitute the constants:
c1 = A
c2 = w * D.x
c3 = w * D.y * z + t * phi
W(x) = c1 * sin(c2 * x + c3)
The derivative is:
W'(x) = c1 * c2 * cos(c2 * x + c3)
Reverting the substitution we get:
W'(x) = A * w * D.x * cos(w * D.x * x + w * D.y * z + t * phi)
which describes the y-component of the tangent at a given position.
Similarly, the bitangent (derivative with respect to z) can be described by
W'(z) = A * w * D.y * cos(w * D.y * z + w * D.x * x + t * phi)
Therefore:
tangent = (1, W'(x), 0)
= (1, A * w * D.x * cos(w * D.x * x + w * D.y * z + t * phi), 0)
bitangent = (0, W'(z), 1)
= (0, A * w * D.y * cos(w * D.y * z + w * D.x * x + t * phi), 1)

Resources