Dưới đây là cổng Java của tôi, luồn lách qua những tình trạng lỗi khi yếu tố quyết định sẽ biến mất với rất thanh lịch IllegalArgumentException
, cách tiếp cận của tôi để đối phó với những "điểm hai điều kiện cách xa nhau "hoặc" nằm trên một đường ". Ngoài ra, điều này tính toán bán kính (và đối phó với các điều kiện đặc biệt) mà cách tiếp cận giao nhau-sườn của bạn sẽ không làm.
public class CircleThree
{
static final double TOL = 0.0000001;
public static Circle circleFromPoints(final Point p1, final Point p2, final Point p3)
{
final double offset = Math.pow(p2.x,2) + Math.pow(p2.y,2);
final double bc = (Math.pow(p1.x,2) + Math.pow(p1.y,2) - offset)/2.0;
final double cd = (offset - Math.pow(p3.x, 2) - Math.pow(p3.y, 2))/2.0;
final double det = (p1.x - p2.x) * (p2.y - p3.y) - (p2.x - p3.x)* (p1.y - p2.y);
if (Math.abs(det) < TOL) { throw new IllegalArgumentException("Yeah, lazy."); }
final double idet = 1/det;
final double centerx = (bc * (p2.y - p3.y) - cd * (p1.y - p2.y)) * idet;
final double centery = (cd * (p1.x - p2.x) - bc * (p2.x - p3.x)) * idet;
final double radius =
Math.sqrt(Math.pow(p2.x - centerx,2) + Math.pow(p2.y-centery,2));
return new Circle(new Point(centerx,centery),radius);
}
static class Circle
{
final Point center;
final double radius;
public Circle(Point center, double radius)
{
this.center = center; this.radius = radius;
}
@Override
public String toString()
{
return new StringBuilder().append("Center= ").append(center).append(", r=").append(radius).toString();
}
}
static class Point
{
final double x,y;
public Point(double x, double y)
{
this.x = x; this.y = y;
}
@Override
public String toString()
{
return "("+x+","+y+")";
}
}
public static void main(String[] args)
{
Point p1 = new Point(0.0,1.0);
Point p2 = new Point(1.0,0.0);
Point p3 = new Point(2.0,1.0);
Circle c = circleFromPoints(p1, p2, p3);
System.out.println(c);
}
}
Xem algorithm from here:
void circle_vvv(circle *c)
{
c->center.w = 1.0;
vertex *v1 = (vertex *)c->c.p1;
vertex *v2 = (vertex *)c->c.p2;
vertex *v3 = (vertex *)c->c.p3;
float bx = v1->xw; float by = v1->yw;
float cx = v2->xw; float cy = v2->yw;
float dx = v3->xw; float dy = v3->yw;
float temp = cx*cx+cy*cy;
float bc = (bx*bx + by*by - temp)/2.0;
float cd = (temp - dx*dx - dy*dy)/2.0;
float det = (bx-cx)*(cy-dy)-(cx-dx)*(by-cy);
if (fabs(det) < 1.0e-6) {
c->center.xw = c->center.yw = 1.0;
c->center.w = 0.0;
c->v1 = *v1;
c->v2 = *v2;
c->v3 = *v3;
return;
}
det = 1/det;
c->center.xw = (bc*(cy-dy)-cd*(by-cy))*det;
c->center.yw = ((bx-cx)*cd-(cx-dx)*bc)*det;
cx = c->center.xw; cy = c->center.yw;
c->radius = sqrt((cx-bx)*(cx-bx)+(cy-by)*(cy-by));
}
http://mathforum.org/library/drmath/view/55233.html –
nhờ một tấn cho đăng câu trả lời cho câu hỏi của bạn. –
Giải pháp của bạn tạo ra kết quả lạ nếu 'B.x - A.x' hoặc' C.x - B.x' bằng 0, bởi vì bạn chia cho 0. – gexicide