Hi all,
I try to find the smallest distance between two circles given in R3 using minlbfgsoptimize but it obviously fails (see attached image).
Each circle is given by its center C, a radius R and a normal vector N. Pairwise perpendicular vectors U and V are calculated with respect to N. All vectors are unit-vectors.
A point on the circle can be evaluated for a given angle alpha in the UV-plane:
Quote:
Circle K = C + R * cos(alpha) * U + R * sin(alpha) * V
For finding the smallest distance between two given circles the squared distance between two points on the circles is calculated and has to be minimized. The points on the circles are given by the angle theta for the first circle and the angle phi for the second circle:
Code:
public static void functionCircleCircle(double[] x, ref double func, object obj)
{
Circle[] circles = (Circle[])obj;
double theta = x[0];
double phi = x[1];
Vector w1 = Math.Cos(theta) * circles[0].U + Math.Sin(theta) * circles[0].V;
Vector w2 = Math.Cos(phi) * circles[1].U + Math.Sin(phi) * circles[1].V;
double d = (circles[1].Center - circles[0].Center + circles[1].Radius * w2 - circles[0].Radius * w1).Norm;
func = d * d;
}
The optimization is done like this:
Code:
// define the circles
// first case
Circle c1 = new Circle(new Point(0, 0, 0), 10, new Vector(0, 0, 1)); // black circle
Circle c2 = new Circle(new Point(0, 0, 30), 10, new Vector(1, 0, 0)); // green circle
// second case
//Circle c1 = new Circle(new Point(0, 0, 0), 10, new Vector(0, 0, 1)); // black circle
//Circle c2 = new Circle(new Point(0, 0, 30), 10, new Vector(0, 1, 0)); // red circle
double[] x = new double[] { 0, 0 }; // initial guess
double epsg = 1.0e-6;
double epsf = 0;
double epsx = 0;
double diffstep = 1.0e-6;
int maxits = 0;
alglib.minlbfgsstate state;
alglib.minlbfgsreport rep;
alglib.minlbfgscreatef(1, x, diffstep, out state);
alglib.minlbfgssetcond(state, epsg, epsf, epsx, maxits);
alglib.minlbfgsoptimize(state, functionCircleCircle, null, circles);
alglib.minlbfgsresults(state, out x, out rep);
Point p1 = circles[0].Eval(x[0]); // eval optimized angle on first circle
Point p2 = circles[1].Eval(x[1]); // eval optimized angle on second circle
LineSegment segment = new LineSegment(p1, p2); // this *should* be the shortest line between the two circles
// Output
Console.WriteLine("Theta = {0}\tPhi = {1}", x[0], x[1]);
Console.WriteLine("Length = {0}", segment.Length);
DrawCircle(circles[0]);
DrawCircle(circles[1]);
DrawLineSegment(segment);
It is clear that the distance in both cases equal each other. But it turns out, that the first case gives the correct result of 21.623 mm, while the second case gives 22.361 mm. In the attached image you can see that the position of the point on the black circle c1 is not optimized.
Can anyone give me a hint for a solution of this problem? Is there another suitable algo in alglib for solving this task while keeping in mind that later on not only the distance between circles but discs must be calculated!?
Thanks in advance,
Alex