Search code examples
algorithmmathlinear-equation

find center of circle when three points are given


I studied this link and coded accordingly but getting Wrong Answer for the example explained in the link, During solving the equation, I subtracted equation 2 from equation 1 and equation 3 from equation 2 and then proceed further. Please check link for clarification.

My code is:

include<stdio.h>
int is_formCircle(float a1,float b1,float a2,float b2,float a3,float b3) {
  float p1=a2-a1;
  float p2=a3-a2;
  float p3=b2-b1;
  float p4=b3-b2;
  float alpha=(a1+a2)*(a1-a2) + (b1+b2)*(b1-b2);
  float beta =(a2+a3)*(a2-a3) + (b2+b3)*(b2-b3);
  float y1=p1*beta - p2*alpha;
  float y2=p2*p3 - p1*p4;
  if(y2==0 || y1==0) return 1;
  float y=y1/y2;
  float x1 = 2*p4*y + beta;
  float x2 = 2*p2;
  float x = x1/x2;
  printf("x=%f  y=%f\n",x,y);
  return 0;
}
int main() {
 float a1,a2,a3,a4,b1,b2,b3,b4;
 a1=4.0;
 b1=1.0;
 a2=-3.0;
 b2=7.0;
 a3=5.0;
 b3=-2.0;
 is_formCircle(a1,b1,a2,b2,a3,b3);
 return 0;
}

MY another Code:

#include<stdio.h>
int is_formCircle(float a1,float b1,float a2,float b2,float a3,float b3) {                  
  float mid1,mid2,mid3,mid4,m1,m2,D,Dx,Dy,x,y;
  mid1 = a1+(a2-a1)/2;
  mid2 = b1+(b2-b1)/2;
  mid3 = a2+(a3-a2)/2;
  mid4 = b2+(b3-b2)/2;
  m1=(b2-b1)/(a2-a1);
  m2=(b3-b2)/(a3-a2);
  m1=-1*m1;
  m2=-1*m2;
  D=m2-m1;
  Dx=mid2-(m1*mid1) + (mid3*m2) - mid4;
  Dy=(m1*(mid3*m2-mid4))-(m2*(mid1*m1-mid2));
  x=Dx/D;
  y=Dy/D;
  printf("%f %f",x,y);    
  return 0;
}
int main() {
 float a1,a2,a3,b1,b2,b3;      
 a1=4.0;
 b1=1.0;
 a2=-3.0;
 b2=7.0;
 a3=5.0;
 b3=-2.0;
 is_formCircle(a1,b1,a2,b2,a3,b3);      
 return 0;
}

Why my code giving Wrong Answer?


Solution

  • I have to say, if you're following the link you listed, it would've helped to keep the variable names the same. We could understand the algorithm much better seeing x1, y1, x2, y2, x3, y3 instead of p1, p2, p3, p4, alpha and beta. In fact, I don't see much in your algorithm that matches the link. I'm not trying to be as harsh as the comments were (and if you're worried about switching float to double, that was a perfectly good case for a typedef), but debugging algorithms is easiest when you don't have to convert variable names.

    I would recommend simply using what they give you for h and k in the link, which is namely done by calculating determinants of 3x3 matrices. You can find lots of references for that.

    I'd make two functions, as follows:

    float calculateH(float x1, float y1, float x2, float y2, float x3, float y3) {
        float numerator = (x2*x2+y2*y2)*y3 - (x3*x3+y3*y3)*y2 - 
                          ((x1*x1+y1*y1)*y3 - (x3*x3+y3*y3)*y1) +
                          (x1*x1+y1*y1)*y2 - (x2*x2+y2*y2)*y1;
        float denominator = (x2*y3-x3*y2) -
                            (x1*y3-x3*y1) +
                            (x1*y2-x2*y1);
        denominator *= 2;
        return numerator / denominator;
    }
    float calculateK(float x1, float y1, float x2, float y2, float x3, float y3) {
        float numerator = x2*(x3*x3+y3*y3) - x3*(x2*x2+y2*y2) -
                          (x1*(x3*x3+y3*y3) - x3*(x1*x1+y1*y1)) +
                          x1*(x2*x2+y2*y2) - x2*(x1*x1+y1*y1);
        float denominator = (x2*y3-x3*y2) -
                            (x1*y3-x3*y1) +
                            (x1*y2-x2*y1);
        denominator *= 2;
        return numerator / denominator;
    }
    

    Then your is_formCircle would simply be:

    float is_formCircle(float x1, float y1, float x2, float y2, float x3, float y3) {
        float h = calculateH(x1, y1, x2, y2, x3, y3);
        float k = calculateK(x1, y1, x2, y2, x3, y3);
        printf("x=%f  y=%f\n",h,k);
    }
    

    There are tons of ways to optimize this, and there's a chance I typoed any of the determinant calculations, but it should get you going.