2013-07-09 11 views
4

Я изучил this link и закодировал соответственно, но получил неправильный ответ для примера, поясненного в ссылке . При решении уравнения я вычитал уравнение 2 из уравнения 1 и уравнения 3 из уравнения 2 и затем продолжайте дальше. Пожалуйста, проверьте ссылку для уточнения.найти центр круга, когда заданы три точки.

Мой код:

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; 
} 

МОЯ другой код:

#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; 
} 

Почему мой код дает неправильный ответ?

+1

Читаемый код, пожалуйста. Как вы могли отладить это, даже если это конкурс? –

+6

'typedef double f;' ** YUCK! ** Нет никакого оправдания. –

+0

Где вы отправляете задание? –

ответ

4

Я должен сказать, что если вы следуете ссылке, которую вы указали, это помогло бы сохранить имена переменных одинаковыми. Мы могли бы лучше понять алгоритм, увидев x1, y1, x2, y2, x3, y3 вместо p1, p2, p3, p4, alpha и beta. На самом деле, я не вижу многого в вашем алгоритме, который соответствует ссылке. Я не пытаюсь быть таким суровым, как комментарии (и если вы беспокоитесь о переключении float в double, это было бы неплохим примером для typedef), но алгоритмы отладки проще всего, когда вам не нужно конвертировать имена переменных.

Я бы порекомендовал просто использовать то, что они дают вам для h и k в ссылке, что сделано путем вычисления детерминант матриц 3x3. Вы можете найти много references.

я хотел бы сделать две функции, а именно:

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; 
} 

Тогда ваш is_formCircle бы просто:

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); 
} 

Есть куча способов оптимизации этого, и есть шанс, что я typoed любой из детерминантных вычислений, но он должен вас поймать.

+0

Спасибо. Я сделал то же самое, используя бумагу и ручку, и сформулировал вещь в своем коде, но не работал, но это прекрасно работает. – avinashse

+1

Добро пожаловать , Я замечаю, что ваш код на самом деле является логической проверкой, чтобы увидеть, можете ли вы сформировать круг из трех точек. Ответ (как вы можете догадаться из объяснения Dr_Sam) всегда «да» - если только три точки не являются коллинеарными.Если они есть, то в этом расчете детерминант в знаменателе будет равен 0. –

+0

Да, я подумал об этом, три точки будут всегда образовывать окружность, если они не коллинеарны, что я делаю, я должен проверить, что точка лежит внутри , вне или по кругу, например, пусть найдутся точки A, B, C, D. Я нахожу центр круга A, B, C, а затем вычисляя радиус (R), а затем вычисляя | AD |. Если (| AD |> R) точка D находится вне круга, то есть ли какой-нибудь быстрый способ сделать это.? – avinashse

4

Решение, которое было дано в ссылке, является «слепым» решением, то есть вы знаете уравнение, стрела решает его.

Однако если вы глубже понять, что стоит за сценой, вы сможете:

  1. Написать более читаемым, надежный, гибкий код.
  2. Отладка легко.

Что происходит, если вы вычтите уравнение 1 из уравнения 2? Вы действительно пытаетесь найти уравнение прямой, описывающее те точки, которые равноудалены от точки 1 и точки 2. Затем вы делаете то же самое с пунктами 2 и 3. Наконец, вы найдете пересечение между ними линиям, которые дает вам центр круга.

Как вы описываете прямую линию точек, эквидистантных к точкам 1 и 2? Вы делаете точку, которая находится посредине двух, и двигайтесь в направлении, перпендикулярном направлению между точками 1 и 2.

Если это не совсем понятно, возьмите бумагу и нарисуйте пример: поместите точки 1 , 2 и 3, найдите две линии и найдите пересечение.

Теперь, когда вы поняли все, изменить свой код с двумя функциями, на которые найти строку на равном расстоянии между двумя точками, еще один, который вычислить пересечение между двумя линиями ...


После правки, код выглядел лучше, хотя это было не просто понять. Я думаю, что ошибка, когда вы решаете для пересечения двух линий, не забывайте, что вы находитесь в параметрической форме:

Dx = (mid4-mid2) - m2*(mid3-mid1); 

lambda=Dx/D; 

x = mid1 + lambda*m1; 
y = mid2 + lambda*1.0; 

Проверено графический с использованием Matlab.

+0

Спасибо за ответ .. Я отредактировал мой код и, возможно, сделал то же самое, что вы сказали, найденные средние точки двух точек и наклон для перпендикулярного биссектриса линии, соединяющей эту две точки, а затем образуют уравнение для этой перпендикулярной биссектрисы, которая затем решена, чтобы найти центр круга. – avinashse

+0

Благодарю вас за ответ, у меня есть один запрос. Что я делаю, я должен проверить, что точка лежит внутри, снаружи или по кругу, например, пусть есть точки A, B, C, D. Я нахожу центр круга A, B, C, а затем вычисляя радиус (R), а затем вычисляя | AD |. Если (| AD |> R) точка D находится вне круга, то есть ли другой быстрый способ сделать это?? – avinashse

+0

@avinashse Остерегайтесь того, что вы должны вычислить | KD | где К - центр круга, а не | AD |. В противном случае это выглядит отлично. Вы также можете проверить | KD |^2> R^2, чтобы вам не нужен квадратный корень, но это не большая оптимизация. –

 Смежные вопросы

  • Нет связанных вопросов^_^