So, I'm trying to understand the dynamic programming algorithm for finding the minimum weighted triangulation decomposition of a convex polygon. For those of you that don't know, triangulation is where we take a convex polygon, and break it up into triangles. The minimum weighted triangulation is the triangulation of a polygon where the sum of all the edges(or perimeter of every triangle) is the smallest.
It's actually a fairly common algorithm, however I just can't grasp it. Here is the algorithm I'm trying to understand:
http://en.wikipedia.org/wiki/Minimum-weight_triangulation#Variations
Here's another description I'm trying to follow(Scroll down to 5.2 Optimal Triangulations):
http://valis.cs.uiuc.edu/~sariel/teach/notes/algos/lec/05_dprog_II.pdf
So I understand this much so far. I take all my vertices, and make sure they are in clockwise order around the perimeter of the original polygon. I make a function that returns the minimum weight triangulation, which I call MWT(i, j) of a polygon starting at vertex i and going to vertex j. This function will be recursive, so the first call should be MWT(0, n-1), where n is the total number of vertices. MWT should test all the triangles that are made of the points i, j, and k, where k is any vertex between those. Here's my code so far:
def MWT(i, j):
if j <= i: return 0
elif j == i+1: return 0
cheap_cost = float("infinity")
for k in range(i, j):
cheap_cost = min(cheap_cost, cost((vertices[i], vertices[j], vertices[k])) + MWT(i, k) + MWT(k, j))
return cheap_cost
However when I run it it overflows the stack. I'm just completely lost and would appreciate if somebody could help direct me in the right direction.
If you guys need any more info just ask.
I think that you want to do
for k in range(i+1, j):
not
for k in range(i, j):
because you never want k to be the same as i or j (otherwise you'll just calculate it for the same values that you're currently running).
Related
Anyone know the worst-case for Himpling's greedy graph coloring algorithm (i.e. what is the worst ratio between its coloring and the optimal coloring).
The basic algorithm colors each vertex one color, and then repeatedly increments a vertex color if it collides with an existing vertex on a common edge. This is similar but not quite the same as the standard greedy coloring on Wikipedia.
One relation between chromatic number (the optimal coloring) and the graph maximum degree is given by Brook's theorem.
Given that by Himpling's algorithm you mean something along these lines:
while no more (u, v) s.t. u.color == v.color
for u in V
for v in V
if (u, v) in E and u.color == v.color
v.color = u.color + 1
The biggest ratio should be 1/V.
I thought about this quesion for a while, and googling "edge" or "vertices" does not return anything useful.
Yes it's very simple for cubic, but not so easy for arbitrary shape in 3D. E.g. a concave body. You might find some diagonal lines but it's not the edge.
This general term for this question is called Convex Hull
It's widely used in GIS
https://gis.stackexchange.com/questions/1200/concave-hull-definition-algorithms-and-practical-solutions
And the most famous algorithm is done by Graham Scan from ACM
GRAHAM_SCAN(Q)
Find p0 in Q with minimum y-coordinate (and minimum x-coordinate if there are ties).
Sorted the remaining points of Q (that is, Q ? {p0}) by polar angle in counterclockwise order with respect to p0.
TOP [S] = 0 ? Lines 3-6 initialize the stack to contain, from bottom to top, first three points.
PUSH (p0, S)
PUSH (p1, S)
PUSH (p2, S)
for i = 3 to m ? Perform test for each point p3, ..., pm.
do while the angle between NEXT_TO_TOP[S], TOP[S], and pi makes a nonleft turn ? remove if not a vertex
do POP(S)
PUSH (S, pi)
return S
http://en.wikipedia.org/wiki/Graham_scan
http://www.personal.kent.edu/~rmuhamma/Compgeometry/MyCG/ConvexHull/GrahamScan/grahamScan.htm
Fun fact: convex OR concave hull has a patent:
https://stackoverflow.com/a/2241263/41948
I am trying to find circumcenter of Given Three point of Triangle……..
NOTE: all these three points are with X,Y and Z Co-Ordinate Means points are in 3D
I know that the circumcenter is the point where the right bisectors intersect….
But for that I have to find middle point of each side then the right bisectors and then intersection point of that …..this is long and error some process……
Is there not any formula which just takes as input these three points of triangle and giving us the Circumcenter of Triangle ……?
Thanks………
The wiki page on Circumscribed circle has it in terms of dot and cross products of the three vertex vectors. It also has a formula for the radius of the circle, if you are so interested.
First of all, you need to make sure that points are not collinear. i.e. do not lie in the same line. For that you need to find the direction cosines of the lines made by three points, and if they have same direction cosines, halt, you can't get circle out of it.
For direction cosine please check this article on wikipedia.
(A way of finding coordinate-geometry and geometry -- based on the theorem that, a perpendicular line from center of circle bisects a chord)
Find the equation of the plane.
This equation must reduce to the form
and the direction cosines (of the line perpendicular to plane determines the plane), so direction cosines of the line perpendicular to this line is
given by this link equations -- 8,9,10 (except replace it for l, m, n).
Find the equation of the lines (all three) in 3-d
(x-x1)/l=(y-y1)/m=(z-z1)/n (in terms of direction cosines) or
(x-x1)/(x2-x1)=(y-y1)/(y2-y1)=(z-z1)/(z2-z1)
Now we need to find the equation of line
a) this perpendicular to the line, from 2 (let l1, m1, n1 be direction cosines of this line)
b) must be contained in place from 1 (let l2, m2, n2 be direction cosines of this line perpendicular to plane)
Find and solve (at least two lines) from 3, sure you will be able to find the center of the circle.
How to find out equation ??? as we are finding the circum-center, we will get our points (i.e. it is the midpoint of the two points) and for a) we have
l1*l+m1*m+n1*n = 0 and l2*l+m2*m+n2*n = 0 where l, m, n are direction cosines of our, line, now solving this two equation, we can get l, m interms of n. And we use this found out (x1,y1,z1) and the value of l, m, 1 and we will have out equation.
The other process is to solve the equation given in this equation
https://stackoverflow.com/questions/5725871/solving-the-multiple-math-equations
Which is the deadliest way.
The other method is using the advantage of computer(by iteration) - as I call it (but for this you need to know the range of the coordinates and it consumes lot of memory)
it's like this (You can make it more precise by incrementing at 1/10) but certainly bad way.
for(i=minXrange, i>=maxXrange; i++){
for(j=minYrange, j>=maxYrange; j++){
for(i=minZrange, i>=maxZrange; k++){
if(((x1-i)^2 + (y1-j)^2 + (z1-k)^2) == (x2-i)^2 + (y2-j)^2 + (z2-k)^2) == for z)){
return [i, j, k];
}
}
}
}
I am trying to generate a 3d tube along a spline. I have the coördinates of the spline (x1,y1,z1 - x2,y2,z2 - etc) which you can see in the illustration in yellow. At those points I need to generate circles, whose vertices are to be connected at a later stadium. The circles need to be perpendicular to the 'corners' of two line segments of the spline to form a correct tube. Note that the segments are kept low for illustration purpose.
[apparently I'm not allowed to post images so please view the image at this link]
http://img191.imageshack.us/img191/6863/18720019.jpg
I am as far as being able to calculate the vertices of each ring at each point of the spline, but they are all on the same planar ie same angled. I need them to be rotated according to their 'legs' (which A & B are to C for instance).
I've been thinking this over and thought of the following:
two line segments can be seen as 2 vectors (in illustration A & B)
the corner (in illustraton C) is where a ring of vertices need to be calculated
I need to find the planar on which all of the vertices will reside
I then can use this planar (=vector?) to calculate new vectors from the center point, which is C
and find their x,y,z using radius * sin and cos
However, I'm really confused on the math part of this. I read about the dot product but that returns a scalar which I don't know how to apply in this case.
Can someone point me into the right direction?
[edit]
To give a bit more info on the situation:
I need to construct a buffer of floats, which -in groups of 3- describe vertex positions and will be connected by OpenGL ES, given another buffer with indices to form polygons.
To give shape to the tube, I first created an array of floats, which -in groups of 3- describe control points in 3d space.
Then along with a variable for segment density, I pass these control points to a function that uses these control points to create a CatmullRom spline and returns this in the form of another array of floats which -again in groups of 3- describe vertices of the catmull rom spline.
On each of these vertices, I want to create a ring of vertices which also can differ in density (amount of smoothness / vertices per ring).
All former vertices (control points and those that describe the catmull rom spline) are discarded.
Only the vertices that form the tube rings will be passed to OpenGL, which in turn will connect those to form the final tube.
I am as far as being able to create the catmullrom spline, and create rings at the position of its vertices, however, they are all on a planars that are in the same angle, instead of following the splines path.
[/edit]
Thanks!
Suppose you have a parametric curve such as:
xx[t_] := Sin[t];
yy[t_] := Cos[t];
zz[t_] := t;
Which gives:
The tangent vector to our curve is formed by the derivatives in each direction. In our case
Tg[t_]:= {Cos[t], -Sin[t], 1}
The orthogonal plane to that vector comes solving the implicit equation:
Tg[t].{x - xx[t], y - yy[t], z - zz[t]} == 0
In our case this is:
-t + z + Cos[t] (x - Sin[t]) - (y - Cos[t]) Sin[t] == 0
Now we find a circle in that plane, centered at the curve. i.e:
c[{x_, y_, z_, t_}] := (x - xx[t])^2 + (y - yy[t])^2 + (z - zz[t])^2 == r^2
Solving both equations, you get the equation for the circles:
HTH!
Edit
And by drawing a lot of circles, you may get a (not efficient) tube:
Or with a good Graphics 3D library:
Edit
Since you insist :) here is a program to calculate the circle at junctions.
a = {1, 2, 3}; b = {3, 2, 1}; c = {2, 3, 4};
l1 = Line[{a, b}];
l2 = Line[{b, c}];
k = Cross[(b - a), (c - b)] + b; (*Cross Product*)
angle = -ArcCos[(a - b).(c - b)/(Norm[(a - b)] Norm[(c - b)])]/2;
q = RotationMatrix[angle, k - b].(a - b);
circle[t_] := (k - b)/Norm[k - b] Sin#t + (q)/Norm[q] Cos#t + b;
Show[{Graphics3D[{
Red, l1,
Blue, l2,
Black, Line[{b, k}],
Green, Line[{b, q + b}]}, Axes -> True],
ParametricPlot3D[circle[t], {t, 0, 2 Pi}]}]
Edit
Here you have the mesh constructed by this method. It is not pretty, IMHO:
I don't know what your language of choice is, but if you speak MatLab there are already a few implementations available. Even if you are using another language, some of the code might be clear enough to inspire a reimplementation.
The key point is that if you don't want your tube to twist when you connect the vertices, you cannot determine the basis locally, but need to propagate it along the curve. The Frenet frame, as proposed by jalexiou, is one option but simpler stuff works fine as well.
I did a simple MatLab implementation called tubeplot.m in my formative years (based on a simple non-Frenet propagation), and googling it, I can see that Anders Sandberg from kth.se has done a (re?)implementation with the same name, available at http://www.nada.kth.se/~asa/Ray/Tubeplot/tubeplot.html.
Edit:
The following is pseudocode for the simple implementation in tubeplot.m. I have found it to be quite robust.
The plan is to propagate two normals a and b along the curve, so
that at each point on the curve a, b and the tangent to the curve
will form an orthogonal basis which is "as close as possible" to the
basis used in the previous point.
Using this basis we can find points on the circumference of the tube.
// *** Input/output ***
// v[0]..v[N-1]: Points on your curve as vectors
// No neighbours should overlap
// nvert: Number of vertices around tube, integer.
// rtube: Radius of tube, float.
// xyz: (N, nvert)-array with vertices of the tube as vectors
// *** Initialization ***
// 1: Tangent vectors
for i=1 to N-2:
dv[i]=v[i+1]-v[i-1]
dv[0]=v[1]-v[0], dv[N-1]=v[N-1]-v[N-2]
// 2: An initial value for a (must not be pararllel to dv[0]):
idx=<index of smallest component of abs(dv[0])>
a=[0,0,0], a[idx]=1.0
// *** Loop ***
for i = 0 to N-1:
b=normalize(cross(a,dv[i]));
a=normalize(cross(dv[i],b));
for j = 0 to nvert-1:
th=j*2*pi/nvert
xyz[i,j]=v[i] + cos(th)*rtube*a + sin(th)*rtube*b
Implementation details: You can probably speed up things by precalculating the cos and sin. Also, to get a robust performance, you should fuse input points closer than, say, 0.1*rtube, or a least test that all the dv vectors are non-zero.
HTH
You need to look at Fenet formulas in Differential Geometry. See figure 2.1 for an example with a helix.
Surfaces & Curves
Taking the cross product of the line segment and the up vector will give you a vector at right-angles to them both (unless the line segment points exactly up or down) which I'll call horizontal. Taking the cross product of horizontal and the line segment with give you another vector that's at right angles to the line segment and the other one (let's call it vertical). You can then get the circle coords by lineStart + cos theta * horizontal + sin theta * vertical for theta in 0 - 2Pi.
Edit: To get the points for the mid-point between two segments, use the sum of the two line segment vectors to find the average.
I'm looking for an algorithm to find the common intersection points between 3 spheres.
Baring a complete algorithm, a thorough/detailed description of the math would be greatly helpful.
This is the only helpful resource I have found so far:
http://mathforum.org/library/drmath/view/63138.html
But neither method described there is detailed enough for me to write an algorithm on.
I would prefer the purely algebraic method described in the second post, but what ever works.
Here is an answer in Python I just ported from the Wikipedia article. There is no need for an algorithm; there is a closed form solution.
import numpy
from numpy import sqrt, dot, cross
from numpy.linalg import norm
# Find the intersection of three spheres
# P1,P2,P3 are the centers, r1,r2,r3 are the radii
# Implementaton based on Wikipedia Trilateration article.
def trilaterate(P1,P2,P3,r1,r2,r3):
temp1 = P2-P1
e_x = temp1/norm(temp1)
temp2 = P3-P1
i = dot(e_x,temp2)
temp3 = temp2 - i*e_x
e_y = temp3/norm(temp3)
e_z = cross(e_x,e_y)
d = norm(P2-P1)
j = dot(e_y,temp2)
x = (r1*r1 - r2*r2 + d*d) / (2*d)
y = (r1*r1 - r3*r3 -2*i*x + i*i + j*j) / (2*j)
temp4 = r1*r1 - x*x - y*y
if temp4<0:
raise Exception("The three spheres do not intersect!");
z = sqrt(temp4)
p_12_a = P1 + x*e_x + y*e_y + z*e_z
p_12_b = P1 + x*e_x + y*e_y - z*e_z
return p_12_a,p_12_b
Probably easier than constructing 3D circles, because working mainly on lines and planes:
For each pair of spheres, get the equation of the plane containing their intersection circle, by subtracting the spheres equations (each of the form X^2+Y^2+Z^2+aX+bY+c*Z+d=0). Then you will have three planes P12 P23 P31.
These planes have a common line L, perpendicular to the plane Q by the three centers of the spheres. The two points you are looking for are on this line. The middle of the points is the intersection H between L and Q.
To implement this:
compute the equations of P12 P23 P32 (difference of sphere equations)
compute the equation of Q (solve a linear system, or compute a cross product)
compute the coordinates of point H intersection of these four planes. (solve a linear system)
get the normal vector U to Q from its equation (normalize a vector)
compute the distance t between H and a solution X: t^2=R1^2-HC1^2, (C1,R1) are center and radius of the first sphere.
solutions are H+tU and H-tU
A Cabri 3D construction showing the various planes and line L
UPDATE
An implementation of this answer in python complete with an example of usage can be found at this github repo.
It turns out the analytic solution is actually quite nice using this method and can tell you when a solution exists and when it doesn't (it is also possible to have exactly one solution.) There is no reason to use Newton's method.
IMHO, this is far easier to understand and simpler than trilateration given below. However, both techniques give correct answers in my testing.
ORIGINAL ANSWER
Consider the intersection of two spheres. To visualize it, consider the 3D line segment N connecting the two centers of the spheres. Consider this cross section
(source: googlepages.com)
where the red-line is the cross section of the plane with normal N. By symmetry, you can rotate this cross-section from any angle, and the red line segments length can not change. This means that the resulting curve of the intersection of two spheres is a circle, and must lie in a plane with normal N.
That being said, lets get onto finding the intersection. First, we want to describe the resulting circle of the intersection of two spheres. You can not do this with 1 equation, a circle in 3D is essentially a curve in 3D and you cannot describe curves in 3D by 1 eq.
Consider the picture
(source: googlepages.com)
let P be the point of intersection of the blue and red line. Let h be the length of the line segment along the red line from point P upwards. Let the distance between the two centers be denoted by d. Let x be the distance from the small circle center to P. Then we must have
x^2 +h^2 = r1^2
(d-x)^2 +h^2 = r2^2
==> h = sqrt(r1^2 - 1/d^2*(r1^2-r2^2+d^2)^2)
i.e. you can solve for h, which is the radius of the circle of intersection. You can find the center point C of the circle from x, along the line N that joins the 2 circle centers.
Then you can fully describe the circle as (X,C,U,V are all vector)
X = C + (h * cos t) U + (h * sin t) V for t in [0,2*PI)
where U and V are perpendicular vectors that lie in a plane with normal N.
The last part is the easiest. It remains only to find the intersection of this circle with the final sphere. This is simply a plug and chug of the equations (plug in for x,y,z in the last equation the parametric forms of x,y,z for the circle in terms of t and solve for t.)
edit ---
The equation that you will get is actually quite ugly, you will have a whole bunch of sine's and cosine's equal to something. To solve this you can do it 2 ways:
write the cosine's and sine's in terms of exponentials using the equality
e^(it) = cos t + i sin t
then group all the e^(it) terms and you should get a quadratic equations of e^(it)'s
that you can solve for using the quadratic formula, then solve for t. This will give you the exact solution. This method will actually tell you exactly if a solution exists, two exist or one exist depending on how many of the points from the quadratic method are real.
use newton's method to solve for t, this method is not exact but its computationally much easier to understand, and it will work very well for this case.
Basically you need to do this in 3 steps. Let's say you've got three spheres, S1, S2, and S3.
C12 is the circle created by the intersection of S1 and S2.
C23 is the circle created by the intersection of S2 and S3.
P1, P2, are the intersection points of C12 and C13.
The only really hard part in here is the sphere intersection, and thankfully Mathworld has that solved pretty well. In fact, Mathworld also has the solution to the circle intersections.
From this information you should be able to create an algorithm.
after searching the web this is one of the first hits, so i am posting the most clean and easy solution i found after some hours of research here: Trilateration
This wiki site contains a full description of a fast and easy to understand vector approach, so one can code it with little effort.
Here is another interpretation of the picture which Eric posted above:
Let H be the plane spanned by the centers of the three spheres. Let C1,C2,C3 be the intersections of the spheres with H, then C1,C2,C3 are circles. Let Lij be the line connecting the two intersection points of Ci and Cj, then the three lines L12,L23,L13 intersect at one point P. Let M be the line orthogonal to H through P, then your two points of intersection lie on the line M; hence you just need to intersect M with either of the spheres.