Fitting ellipse with fixed axes ratio - math

My problem is such that I need to reconstruct a circular surface which is observed from an oblique angle so that it shows in the image as an ellipse. From other image parts I can construct the scale in X and Y directions so that I have knowledge of the expected ratio of the axes of the ellipse. The ellipse in question can be defined by points which cover about 1/3 of its circumference, equally distributed where the shorter axis cuts the circumference.
While in principle it's possible to fit an ellipse using these data points (e.g. using Markwardt's ellipse fitting which implements a flavour of the Levenberg-Marquardt technique), it might return wrong parameters as the ratio of axes is not well defined by the data coverage (the excentricity is around 0.3, the ratio of the axes is about 1.05).
I'm looking for an algorithm which allows to give additional constraints when fitting an ellipse or pointers how to tackle that problem.
Neither a search here nor my google-foo returned anything.

Related

Distributing points evenly spaced within a sphere

I am looking for an algorithm to distribute a bunch of points (could be anywhere from a few hundred to millions) within a sphere. In this case the sphere is centered at (0,0,0).
For random points a simple method is
repeat
x:=random*diameter-radius;
y:=random*diameter-radius;
z:=random*diameter-radius;
until ((x*x+y*y+z*z)<(radius*radius));
But I want to get the points evenly spaced within the sphere and without bunching at the poles.
Any good tricks/algorithms/formulas/code snippet to accomplish this?
You could do something like this:
Put the center of your sphere at a random position within an infinite volume of evenly-spaced points, like a tetrahedral or cubic lattice.
Enumerate points in order of increasing distance from the center until you have the right number.
Rescale the selected points around the center so that the distance to the furthest point is equal to the desired radius.
If you need evenly spaced points - just place them in grid nodes.
Sphere with radius R has volume
V=4/3*Pi*R^3
so for placing N points every cell of cubic grid (perhaps you might want to use hexagonal close packing) should have volume
v=4/3*Pi*R^3/N
and edge length
l = R * (4*Pi/(3*N))^1/3
Then generate points in coordinates (a*l, b*l, c*l) where a,b,c are integers limited by -R..+R (with appropriate sum of squares).
Proposed approach is quite rough estimation and perhaps some points from N needed ones might run outside of the sphere. In this case one have to diminish cell size or use more exact value - it might be calculated using 3D analog of Gauss circle formula ()
Thanks for the explanation by joriki. The above formula has been explained in proof of the formula mentioned. But the formula has some limitations. The cube length can be 2 (-1 to 1 in all directions). From the above concept, mentioned by joriki or proof of the formula mentioned we can generalize for the cube of any length (i.e 2a (-a to a in all directions)). Here 2a is the side length of the cube.
$a^6-(a^2-x^2 )(a^2-y^2)(a^2-z^2)=x^2 a^2 (a^2-\frac{z^2}{2}-\frac{y^2}{2}+\frac{y^2 z^2}{3a^2})+y^2 a^2 (a^2-\frac{z^2}{2}-\frac{x^2}{2}+\frac{x^2 z^2}{3a^2})+z^2 a^2 (a^2-\frac{x^2}{2}-\frac{y^2}{2}+\frac{y^2 x^2}{3a^2})$
$x'=xa \sqrt{a^2-\frac{z^2}{2}-\frac{y^2}{2}+\frac{y^2 z^2}{3a^2}}$,
$y'=ya \sqrt{a^2-\frac{z^2}{2}-\frac{x^2}{2}+\frac{x^2 z^2}{3a^2}}$,
$z'=za \sqrt{a^2-\frac{x^2}{2}-\frac{y^2}{2}+\frac{y^2 x^2}{3a^2}}$,
From the above equation, we can easily separate the (x',y',z') as explained in 1. The above equation will readily find the mapping of the generalized length of the cube to a sphere. I hope this will be helpful.
Form the above equation we can also find the evenly distribution of points within the sphere by varying the grid size of the cube. By discretizing the cube into different grids and simultaneously mapping into the sphere will give the evenly distribution of points within the sphere.
Kindly ignore some typos.
C++ code for evenly distributing points within the sphere:-
for(x=-a;x<=a;x=x+n)
for(y=-a;y<=a;y=y+n)
{
for(z=-a;z<=a;z=z+n)
{
xnew=x*a*(sqrt((a*a)-(y*y)/(2)-(z*z)/(2)+(y*y*z*z)/(3*a*a)));
ynew=y*a*(sqrt((a*a)-(z*z)/(2)-(x*x)/(2)+(x*x*z*z)/(3*a*a)));
znew=z*a*(sqrt((a*a)-(x*x)/(2)-(y*y)/(2)+(y*y*x*x)/(3*a*a)));
cout<<" "<<xnew<<" "<<ynew<<" "<<znew<<endl;
}
}
}
Note:- Here in code, n is the grid size of a cube.

Getting the boundary of a Bezier curve

I have points list and control points list to draw a Bezier curve.
Please let me know how to calculate the boundary rectangle of the Bezier curve.
var pointsList = [CGPoint(34, 23), ... , CGPoint(23, 85)]
var controlPoints = [CGPoint(45, 34), ..., CGPoint(55, 99)]
Normally not really a hard problem, covered over on http://pomax.github.io/bezierinfo/#boundingbox:
Compute the x and y derivatives, which is super easy to do,
Find all roots (derivative=0) for both derivatives, let's call those the sets r{x} and r{y}, then
Compute the corresponding value sets bezier{x} and bezier{y} for those roots. Then,
Your bounding box has corners defined by the lowest and highest values min/max values in those sets.
In this, only step 2 might be a bit tricky if you're using high order bezier curves. Once your curve consists of more than four points, you can't use symbolic maths to find the roots and it's far easier to just run through the derivative curve and see where the resulting coordinates have a value close enough to zero to treat them as approximate root.
Your graphic looks like it's simply a series of connected cubic Bezier curves, in which case the root finding is easy (the derivatives will be quadratic curves, you learn how to find the roots for those in high school using the quadratic equation), and the box procedure is simply "compute the bounding box for each cubic curve section, and when you're done, the full bounding box simply uses the min/max values across all individual boxes".

Find minimum set of rays intersecting all voxels

Okay first I wasn't sure if this was better suited to the MathSO so apologies if it needs migrating.
I have a 3D grid of points (representing the centers of voxels) with pitch varying in each dimension, but regular. For example resolution may be 100 by 50 by 40 for a cube shaped object.
Giving me nVox = 200,000.
For each voxel - I would like to cast (nVox - 1) rays, ending at the center, and originating from each of the other voxels.
Now there is obviously a lot of overlap here but I am having trouble finding how to calculate the minimum set of rays required. This sounds like a problem that has an elegant solution, I am however struggling to find it.
As a start, it is obvious that you only need to compute
[nVox * (nVox - 1)] / 2
of the rays, as the other half will simply be in the opposite directions. It is also easy in the 2D case to combine all of those parallel to one of the grid axes (and the two diagonals).
So how do I find the minimum set of rays I need, to pass from all voxel centers, to all others?
If someone could point me in the right direction that'd be great. Any and all help will be much appreciated.
Your problem really isn't about three dimensions in any specific way. All the conceptual complexity is present in the two dimensional case.
Instead of connecting points individually, think about the set of lines that pass through at least two points on your grid. Thus instead of thinking about points initially, think about directions. For 2-D these directions are slopes of lines. These slopes have to be rational numbers, since they intersect points on an integer lattice. Since you have a finite lattice, the numerator and the denominator of the slope can be bounded by the size of the figure. So your underlying problem is enumerating possible slopes for rational numbers of bounded "height" (math jargon).
There's an algorithm for that. It's the one used to generate the Farey sequence of reduced fractions. If your figure is N pixels wide, there will (in general) be a slope with denominator N in the somewhere, but there can't be a slope in reduced form with denominator >N; it wouldn't fit.
It's easier to deal with slopes between 0 and 1 directly. You get the other directions by two operations: negating the slope and by interchanging axes. For three dimensions, you need two slopes to define a direction.
Given an arbitrary direction (no necessarily a rational one as above), there's a perpendicular linear space of dimension k-1; for 3-D that's a plane. Projecting a 3-D parallelpiped onto this plane yields a hexagon in general; two vertices project onto the interior, six project to the vertices of the hexagon.
For a given discrete direction, there's a minimal bounding box on the integer lattice such that two opposite vertices lie along that direction. As long as that bounding box fits within your original grid, each of the interior points of the projection each correspond to a line that intersects your grid in at least two points.
In summary, enumerate directions, then for each direction enumerate where that direction intersects your grid in at least two points.

scatterplot3d package; how do you re-size a regression plane

I am interested in generating a series of simple 3d scatterplots which include regression planes without interactions using the scatterplot3d function in R. The following code generates almost what I am after with one problem- in many cases the regression plane extends outside of the bounding box (e.g. in this case, the corner nearest x, y and z =0). I tried changing the axis limits to increase the box size, but this does not alter the axis ranges as specified (which, according to the package documentation is an unfixed bug). Is there a way to either 1) re-draw the box to include the entire plane or 2) shrink the plane to include only the portion within the box?
example data
bugs<-c(335.20,8.68,1.94,3.22,21.79,11.16,1618.00,108.76,250.59,400.81,233.86,15.05,274.62,419.21)
max_dq<-c(0.015,0.001,0.001,0.001,0.002,0.007,0.04,0.001,0.014,0.003,0.002,0.006,0.004,0.013)
since_dist<-c(21,58,5,1,1,19,42,33,22,300,240,79,327,42)
library(scatterplot3d)
3 d plot
reg_plt<-scatterplot3d(max_dq,since_dist,bugs,angle=50)
regression plane
reg_plt$plane3d(lm(bugs~max_dq+since_dist))

Compute a radius scale factor to construct n-sided reqular convex polygons of equal area

I have a computer graphics plotting application where we often plot regular convex polygon shapes as symbols for different data points. I'd like to scale the radius (aka circumradius, distance from center to vertex) of the polygons so that polygons with different numbers of sides all have equal area (so presumably similar perceptual impact). i.e. if a circle with radius=1 has area Pi*radius^2, how much do I need to scale the radius to get a square or a triangle with the same area? What would the formula be to compute this for regular polygons with arbitrary numbers of sides?
Seems like this should be a simple geometry/algebra problem, but that was a long time ago... :-)
Using the formula below (taken from this site):
one can derive that:
R = sqrt(2*area / (N*sin(2*pi/N)))

Resources