点到点的距离:dist = sqrt(dx * dx + dy * dy); 但是sqrt太慢了,我不能接受。我发现了一种名为Taylor McLaughlin Series的方法来估算书上两点的距离。但我无法理解以下代码。感谢任何帮助我的人。
#define MIN(a, b) ((a < b) ? a : b)
int FastDistance2D(int x, int y)
{
// This function computes the distance from 0,0 to x,y with 3.5% error
// First compute the absolute value of x, y
x = abs(x);
y = abs(y);
// Compute the minimum of x, y
int mn = MIN(x, y);
// Return the distance
return x + y - (mn >> 1) - (mn >> 2) + (mn >> 4);
}
我已经查阅了有关McLaughlin系列的相关数据,但我仍然无法理解返回值如何使用McLaughlin系列来估算该值。谢谢大家〜
答案 0 :(得分:1)
此任务几乎与另一个任务重复: Very fast 3D distance check?
并且链接到了很棒的文章: http://www.azillionmonkeys.com/qed/sqroot.html
在文章中,您可以找到用于近似根的不同方法。例如,这个可能适合你:
int isqrt (long r) {
float tempf, x, y, rr;
int is;
rr = (long) r;
y = rr*0.5;
*(unsigned long *) &tempf = (0xbe6f0000 - *(unsigned long *) &rr) >> 1;
x = tempf;
x = (1.5*x) - (x*x)*(x*y);
if (r > 101123) x = (1.5*x) - (x*x)*(x*y);
is = (int) (x*rr + 0.5);
return is + ((signed int) (r - is*is)) >> 31;
}
如果您可以快速计算根操作,则可以常规方式计算距离:
return isqrt(a*a+b*b)
还有一个链接: http://www.flipcode.com/archives/Fast_Approximate_Distance_Functions.shtml
u32 approx_distance( s32 dx, s32 dy )
{
u32 min, max;
if ( dx < 0 ) dx = -dx;
if ( dy < 0 ) dy = -dy;
if ( dx < dy )
{
min = dx;
max = dy;
} else {
min = dy;
max = dx;
}
// coefficients equivalent to ( 123/128 * max ) and ( 51/128 * min )
return ((( max << 8 ) + ( max << 3 ) - ( max << 4 ) - ( max << 1 ) +
( min << 7 ) - ( min << 5 ) + ( min << 3 ) - ( min << 1 )) >> 8 );
}
答案 1 :(得分:0)
你是对的sqrt
功能很慢。但你真的需要计算距离吗?
在很多情况下,您可以使用距离² 例如。
100 > distance
是否可以检查10000 > distanceSquared
使用程序中的ditance而不是距离,通常可以避免计算sqrt
。
这取决于您的申请,如果这是您的选择,但总是值得考虑。