我研究了this link并进行了相应的编码,但是对链接中解释的示例进行了错误的答案, 在求解方程期间,我从方程1中减去方程2,从方程2中减去方程3,然后进一步进行。请查看链接以获得澄清。
我的代码是:
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;
}
为什么我的代码给出了错误的答案?
答案 0 :(得分:4)
链接中给出的解决方案是一个“盲目”解决方案,即你知道方程式,繁荣解决它。
然而,如果您更深入地了解幕后背后的内容,您将能够:
从等式2中减去等式1时会发生什么?你实际上试图找到直线的方程,描述与点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以图形方式检查。
答案 1 :(得分: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);
}
有很多方法可以对此进行优化,并且我有可能将任何决定因素计算错误,但它应该让你前进。