Given
x1,y1,
d,
r,
and x2,y2
How would I find x3,y3 and x4,y4?
Construct two equations.
At first, tangent vector P31=(x3-x1, y3-y1) should be perpendicular to radius-vector P32=(x3-x2, y3-y2), so dot product of these vectors is zero.
At second, squared length of P31 is expressed through d and r using Pythagorean theorem.
Then solve system of two equations and get two solutions for both tangent points.
Note that this task has little relation to programming - it is just math.
Related
I have data points in a 2D coordinate space that I want to linearly transform to another coordinate space. The image below will make things a little clear.
The data points I have are in the gray coordinate space (left-top corner A is the x=0,y=0 point). I want to transform all points to the pink coordinate system, for which B is its x=0,y=0 point.
How would I go about doing that?
This is not a linear transformation.
Define this "coordinate system" as a convex quad, as follows:
The vertex coordinates are in parameter space u, v. Interpolating along one direction and then the other gives a general point:
This is bi-linear in parameters u, v. It only becomes linear if A + D - B - C = 0, i.e. the quad is a parallelogram.
Transforming between such coordinate systems:
Assume (required) that these ABCD vertices are embedded in a "global" Cartesian space
Convert from the parameter space of the first system to the global space using interpolation as above
Convert back to the parameter space by inverting the above equation, solving a pair of simultaneous equations:
Solutions for u, v:
1 for a parallelogram (G = 0)
2 for a general convex quad, since the coordinate lines (gray) cross a singularity in each direction
0 for a concave quad (complex solutions)
I'm trying to code the Ritter's bounding sphere algorithm in arbitrary dimensions, and I'm stuck on the part of creating a sphere which would have 3 given points on it's edge, or in other words, a sphere which would be defined by 3 points in N-dimensional space.
That sphere's center would be the minimal-distance equidistant point from the (defining) 3 points.
I know how to solve it in 2-D (circumcenter of a triangle defined by 3 points), and I've seen some vector calculations for 3D, but I don't know what the best method would be for N-D, and if it's even possible.
(I'd also appreciate any other advice about the smallest bounding sphere calculations in ND, in case I'm going in the wrong direction.)
so if I get it right:
Wanted point p is intersection between 3 hyper-spheres of the same radius r where the centers of hyper-spheres are your points p0,p1,p2 and radius r is minimum of all possible solutions. In n-D is arbitrary point defined as (x1,x2,x3,...xn)
so solve following equations:
|p-p0|=r
|p-p1|=r
|p-p2|=r
where p,r are unknowns and p0,p1,p2 are knowns. This lead to 3*n equations and n+1 unknowns. So get all the nonzero r solutions and select the minimal. To compute correctly chose some non trivial equation (0=r) from each sphere to form system of n+1 =equations and n+1 unknowns and solve it.
[notes]
To ease up the processing you can have your equations in this form:
(p.xi-p0.xi)^2=r^2
and use sqrt(r^2) only after solution is found (ignoring negative radius).
there is also another simpler approach possible:
You can compute the plane in which the points p0,p1,p2 lies so just find u,v coordinates of these points inside this plane. Then solve your problem in 2D on (u,v) coordinates and after that convert found solution form (u,v) back to your n-D space.
n=(p1-p0)x(p2-p0); // x is cross product
u=(p1-p0); u/=|u|;
v=u x n; v/=|v|; // x is cross product
if memory of mine serves me well then conversion n-D -> u,v is done like this:
P0=(0,0);
P1=(|p1-p0|,0);
P2=(dot(p2-p0,u),dot(p2-p0,v));
where P0,P1,P2 are 2D points in (u,v) coordinate system of the plane corresponding to points p0,p1,p2 in n-D space.
conversion back is done like this:
p=(P.u*u)+(P.v*v);
My Bounding Sphere algorithm only calculates a near-optimal sphere, in 3 dimensions.
Fischer has an exact, minimal bounding hyper-sphere (N dimensions.) See his paper: http://people.inf.ethz.ch/gaertner/texts/own_work/seb.pdf.
His (C++/Java)code: https://github.com/hbf/miniball.
Jack Ritter
jack#houseofwords.com
I came across this link http://www.mathopenref.com/coordpolygonarea2.html
It explains how to calculate the area of a polygon and helps to identify whether the polygon vertices we entered is clockwise or counter clockwise.
If area value is +ve, it is clockwise, if it is -nv then it is in counterclockwise.
My requirement is to identify only whether it is clockwise or counterclockwise. Is this rule will work correctly (though there are limitations as mentioned in the link). I have only regular polygons (not complicated, no self intersections) but the vertices are more.
I am not interested in the area value accuracy, just to know the ring rotation.
Any other thought on this.
For convex polygons:
Select two edges with a common vertex.
Lets say, edge1 is between vertex A and B. Edge2 is between vertex B and C.
Define to vectors: vect1: A----->B
vect2: B----->C
Cross product vect1 and vect2.
If the result is positive, the sequence A-->B-->C is Counter-clockwise.
If the result is negative, the sequence A-->B-->C is clockwise.
If you have only convex polygons (and all regular polygons are convex), and if your points are all organized consistently--either all counterclockwise or all clockwise--then you can determine which by just computing the (signed) area of one triangle determined by any three consecutive points. This is essentially computing the cross product of the two vectors along the two edges.
I have a problem. Suppose we have a single cubic bezier curve defined by four control points. Now suppose, the curve is cut from a point and each segment is again represented using cubic bezier curves. So, now if we are given two such beziers B1 and B2, is there a way to know if they can be joined to form another bezier curve B? This is to simplify the geometry by joining two curves and reduce the number of control points.
Some thoughts about this problem.
I suggest there was initial Bezier curve P0-P3 with control points P1 and P2
Let's make two subdivisions at parameters ta and tb.
We have now two subcurves (in yellow) - P0-PA3 and PB0-P3.
Blue interval is lost.
PA1 and PB2 - known control points. We have to find unknown P1 and P2.
Some equations
Initial curve:
C = P0*(1-t)^3+3*P1(1-t)^2*t+3*P2*(1-t)*t^2+P3*t^3
Endpoints:
PA3 = P0*(1-ta)^3+3*P1*(1-ta)^2*ta+3*P2*(1-ta)*ta^2+P3*ta^3
PB0 = P0*(1-tb)^3+3*P1*(1-tb)^2*tb+3*P2*(1-tb)*tb^2+P3*tb^3
Control points of small curves
PA1 = P0*(1-ta)+P1*ta => P1*ta = PA1 – P0*(1-ta)
PB2 = P2*(1-tb)+P3*tb => P2(1-tb) = PB2 – P3*tb
Now substitute unknown points in PA3 equation:
**PA3***(1-tb) = **P0***(1-ta)^3*(1-tb)+3*(1-ta)^2*(1-tb)*(**PA1** – **P0***(1-ta))+3*(1-ta)*ta^2*( **PB2** – **P3***tb)+**P3***ta^3*(1-tb)
(some multiplication signs have been lost due to SO formatting)
This is vector equation, it contains two scalar equations for two unknowns ta and tb
PA3X*(1-tb) = P0X*(1-ta)^3*(1-tb)+3*(1-ta)^2*(1-tb)*(PA1X – P0X*(1-ta))+3*(1-ta)*ta^2*( PB2X – P3X*tb)+P3X*ta^3*(1-tb)
PA3Y*(1-tb) = P0Y*(1-ta)^3*(1-tb)+3*(1-ta)^2*(1-tb)*(PA1Y – P0Y*(1-ta))+3*(1-ta)*ta^2*( PB2Y – P3Y*tb)+P3Y*ta^3*(1-tb)
This system might be solved both numerically and analytically (indeed Maple solves it with very-very big cubic formula :( )
If we have points with some error, that makes sense to build overdetermined equation system for some points (PA3, PB0, PA2, PB1) and solve it numerically to minimize deviations.
You will find a quite simple solution here: https://math.stackexchange.com/a/879213/65203.
When you split a Bezier, the vectors formed by the last two control points of the first section and the first two control points of the second section are collinear and the ratio of their lengths leads to the value of the parameter at the split. Verifying that the common control point matches that value of the parameter is an easy matter (to avoid the case of accidental collinearity).
Given a general planar 3D polygon, is there a general way to find the orthonormal basis for that planar polygon?
The most straight forward way to do it is to assume to take the first 3 points of the polygon, and form two vectors each, and these are the two orthonormal basis vectors that we are looking for. But the problem for this approach is that these 3 points may line on the same line in the polygon, and hence instead of getting two orthonormal vectors, we get only one.
Another approach to find the second orthonormal vector is to loop through the polygon and find another point that forms a different orthonormal vector than the first one, but this approach is susceptible to numerical errors (e.g, what if the second vector is almost the same with the first vector? The numerical errors can be significant).
Is there any other better approach?
You can use the cross product of any two lines connected by any two vertices. If the cross product is too low then you're in degenerate territory.
You can also take the centroid (the avg of the points, which is guaranteed to lie on the same plane) and do pick the largest of any two cross products of the vectors from the centroid to any vertex. This will be the most accurate normal. Please note that if the largest cross product is small, you may have an inaccurate normal.
If you can't find any cross product that isn't close to 0, your original poly is degenerate and a normal will be hard to find. You could use arbitrary precision or adaptive precision algebra in this case, but, of course, the round-off error is already significant in the source data, so this may not help. If possible, remove degenerate polys first, and if you have to, sew the mesh back up :).
It's a bit ott but one way would be to compute the covariance matrix of the points, and then diagonalise that. If the points are indeed planar then one of the eigenvalues of the covariance matrix will be zero (or rather very small, due to finite precision arithmetic) and the corresponding eigenvector will be a normal to the plane; the other two eigenvectors will span the plane of the polygon.
If you have N points, and the i'th coordinate of the k'th point is p[k,i], then the mean (vector) and (3x3) covariance matrix can be computed by
m[i] = Sum{ k | p[k,i]}/N (i=1..3)
C[i,j] = Sum{ k | (p[k,i]-m[i])*(p[k,j]-m[j]) }/N (i,j=1..3)
Note that C is symmetric, so that to find how to diagonalise it you might want to look up the "symmetric eigenvalue problem"