public void AddCircle(Circle2d circle, Style style) { Objects.Add(circle); Styles[circle] = style; Bounds.Contain(circle.Bounds); }
public void AddCircle(Circle2d circle) { Objects.Add(circle); Bounds.Contain(circle.Bounds); }
public DistPoint2Circle2(Vector2d PointIn, Circle2d circleIn) { point = PointIn; circle = circleIn; }
public ContMinCircle2(IList <Vector2d> pointsIn, double epsilon = 1e-05) { mEpsilon = epsilon; mUpdate[0] = null; mUpdate[1] = UpdateSupport1; mUpdate[2] = UpdateSupport2; mUpdate[3] = UpdateSupport3; Circle minimal; var support = new Support(); double distDiff = 0; Points = pointsIn; int numPoints = pointsIn.Count; int[] permutation = null; var r = new Random(); if (numPoints >= 1) { // Create identity permutation (0,1,..,numPoints-1). permutation = new int[numPoints]; for (int i = 0; i < numPoints; ++i) { permutation[i] = i; } // Generate random permutation. for (int i = numPoints - 1; i > 0; --i) { int j = r.Next() % (i + 1); if (j != i) { int save = permutation[i]; permutation[i] = permutation[j]; permutation[j] = save; } } minimal = new Circle(Points[permutation[0]], 0); support.Quantity = 1; support.Index[0] = 0; // The previous version of the processing loop is // i = 1; // while (i < numPoints) // { // if (!support.Contains(i, permutation, mEpsilon)) // { // if (!Contains(*permutation[i], minimal, distDiff)) // { // UpdateFunction update = mUpdate[support.Quantity]; // Circle circle = (this->*update)(i, permutation, // support); // if (circle.Radius > minimal.Radius) // { // minimal = circle; // i = 0; // continue; // } // } // } // ++i; // } // This loop restarts from the beginning of the point list each time // the circle needs updating. Linus Källberg (Computer Science at // Mälardalen University in Sweden) discovered that performance is // better when the remaining points in the array are processed before // restarting. The points processed before the point that caused the // update are likely to be enclosed by the new circle (or near the // circle boundary) because they were enclosed by the previous circle. // The chances are better that points after the current one will cause // growth of the bounding circle. for (int i = 1 % numPoints, n = 0; i != n; i = (i + 1) % numPoints) { if (!support.Contains(i, Points, permutation, mEpsilon)) { if (!Contains(Points[permutation[i]], ref minimal, ref distDiff)) { var updateF = mUpdate[support.Quantity]; Circle circle = updateF(i, permutation, support); if (circle.Radius > minimal.Radius) { minimal = circle; n = i; } } } } } else { throw new Exception("ContMinCircle2: Input must contain points\n"); } Result = new Circle2d(minimal.Center, Math.Sqrt(minimal.Radius)); }
public void AddCircle(Circle2d circle) { CurrentLayer.Objects.Add(circle); Bounds.Contain(circle.Bounds); }
// If you think your points are nearly circular, use this. The circle is of // the form C'[0]+C'[1]*X+C'[2]*Y+C'[3]*(X^2+Y^2), where Length(C') = 1. The // function returns C = (C'[0]/C'[3],C'[1]/C'[3],C'[2]/C'[3]), so the fitted // circle is C[0]+C[1]*X+C[2]*Y+X^2+Y^2. The center is (xc,yc) = // -0.5*(C[1],C[2]) and the radius is r = sqrt(xc*xc+yc*yc-C[0]). public static double FitCircle2(Vector2d[] points, out Circle2d circle) { DenseMatrix A = new DenseMatrix(4, 4); int numPoints = points.Length; for (int i = 0; i < numPoints; ++i) { double x = points[i].x; double y = points[i].y; double x2 = x * x; double y2 = y * y; double xy = x * y; double r2 = x2 + y2; double xr2 = x * r2; double yr2 = y * r2; double r4 = r2 * r2; A[0, 1] += x; A[0, 2] += y; A[0, 3] += r2; A[1, 1] += x2; A[1, 2] += xy; A[1, 3] += xr2; A[2, 2] += y2; A[2, 3] += yr2; A[3, 3] += r4; } A[0, 0] = (double)numPoints; for (int row = 0; row < 4; ++row) { for (int col = 0; col < row; ++col) { A[row, col] = A[col, row]; } } double invNumPoints = 1.0 / (double)numPoints; for (int row = 0; row < 4; ++row) { for (int col = 0; col < 4; ++col) { A[row, col] *= invNumPoints; } } SymmetricEigenSolver es = new SymmetricEigenSolver(4, 1024); es.Solve(A.Buffer, SymmetricEigenSolver.SortType.Increasing); double[] evector = new double[4]; es.GetEigenvector(0, evector); double inv = 1.0 / evector[3]; // TODO: Guard against zero divide? Vector3d coefficients = Vector3d.Zero; for (int row = 0; row < 3; ++row) { coefficients[row] = inv * evector[row]; } Vector2d center = new Vector2d(-0.5 * coefficients[1], -0.5 * coefficients[2]); double r = Math.Sqrt(Math.Abs(center.LengthSquared - coefficients[0])); circle = new Circle2d(center, r); // For an exact fit, numeric round-off errors might make the minimum // eigenvalue just slightly negative. Return the absolute value since // the application might rely on the return value being nonnegative. return(Math.Abs(es.GetEigenvalue(0))); }