计算两个 CGPoint 之间距离的最快方法?

发布于 2025-01-01 21:15:49 字数 295 浏览 1 评论 0原文

两点之间的距离:

sqrt((x1-x2)^2 + (y1-y2)^2)

有没有办法在 Objective-C 中更快地进行数学计算?

编辑:我想我需要澄清上面。我写上面的公式只是为了澄清我使用什么公式来计算距离。 ^ 并不意味着表示 xor - 我只是想表示数学公式,而不使用任何函数,如 pow 或任何东西,所以我打算使用 ^ 来“提高电源关闭”。我想知道是否有人知道使用按位运算符或以其他方式在汇编中编写代码是否会给出优化版本。我正在 iPhone / iPad 应用程序中使用该公式。

Distance between two points:

sqrt((x1-x2)^2 + (y1-y2)^2)

Is there a way to do this math faster in objective-C ?

EDIT: I think I need to clarify above. I wrote the formula above just to clarify what formula I am using to calculate the distance. ^ is not meant to represent xor - I just wanted to represent the mathematical formula without using any functions like pow or anything, so I meant to use ^ to "raise to the power off". I was wondering if anyone knows if using bitwise operators, or otherwise writing code in assembly would give an optimized version. I am using the formula in an iPhone / iPad application.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

扬花落满肩 2025-01-08 21:15:49

不,如果您需要精确的距离,则无法超越该公式。

虽然需要明确的是 ^ 不是一个对值进行平方的运算符,而是一个进行异或的位运算符。

你将需要类似的东西

double dx = (x2-x1);
double dy = (y2-y1);
double dist = sqrt(dx*dx + dy*dy);

如果你可以只使用平方(当你只想做像按距离排序这样的事情时,这很有用,你可以使用更高效的

double dx = (x2-x1);
double dy = (y2-y1);
double dist = dx*dx + dy*dy;

这些至少与解决方案一样好。在最坏的情况下, pow() 将使用堆栈并且效率较低,但在这种情况下,您的编译器可能会将其转换为 x*x 。

No, if you need the exact distance you cannot beat that formula.

Although to be clear ^ is not an operator for squaring a value, but a bit operator that does xor.

you will need something like

double dx = (x2-x1);
double dy = (y2-y1);
double dist = sqrt(dx*dx + dy*dy);

If you can live with just the square (which is useful when you just want to do something like sort by distance, you can use the much more efficient

double dx = (x2-x1);
double dy = (y2-y1);
double dist = dx*dx + dy*dy;

These will be at least as good as a solution pow. At worst, pow() will use the stack and be less efficient, but maybe your compiler turns it into x*x for this case.

别理我 2025-01-08 21:15:49

只是将其作为一个简单、美观的解决方案提供。它很可能并不比之前给出的任何更快,只是更短。我个人正在使用hypot

double dist = hypot((x1-x2), (y1-y2));

根据docs,这将返回“(x^2+y^2) 的平方根。 ”

Just offering this as a simple, nice looking solution. It is most likely not any faster than any previously given, just shorter. I personally am using hypot.

double dist = hypot((x1-x2), (y1-y2));

Per the docs, this will return you "The square root of (x^2+y^2)."

雨落星ぅ辰 2025-01-08 21:15:49

在 Intel Mac 上,Clang 将编译:

double distance = ({double d1 = x1 - x2, d2 = y1 - y2; sqrt(d1 * d1 + d2 * d2); });

总计 6 条数学指令:sub、mul、sub、mul、add、sqrt;很难击败它。 (sqrt 是一条指令,尽管它需要多个周期)。

On an Intel Mac Clang will compile:

double distance = ({double d1 = x1 - x2, d2 = y1 - y2; sqrt(d1 * d1 + d2 * d2); });

into a grand total of 6 instructions for the maths: sub, mul, sub, mul, add, sqrt; pretty hard to beat that. (sqrt is a single instruction, though it takes multiple cycles).

欢你一世 2025-01-08 21:15:49
double dist = sqrt ( pow((x1-x2), 2) + pow((y1-y2), 2) );

考虑到x1、x2、y1、y2floatdouble或整数。

double dist = sqrt ( pow((x1-x2), 2) + pow((y1-y2), 2) );

considering x1, x2, y1, y2 are float or double or integer.

拥抱我好吗 2025-01-08 21:15:49

这里唯一可以改进的是平方根计算功能。

我尝试过这两个函数(在 关于平方根计算的维基百科文章中找到)来计算近似值平方根值:

float fsqrt(float x)
{
  float xhalf = 0.5f * x;
  union
  {
    float x;
    int i;
  } u;

  u.x = x;
  u.i = 0x5f3759df - (u.i >> 1);
  x *= u.x * (1.5f - xhalf * u.x * u.x);

  return x;
}

float fsqrt2(float z)
{
    union
    {
        int tmp;
        float f;
    } u;

    u.f = z;

    /*
     * To justify the following code, prove that
     *
     * ((((val_int / 2^m) - b) / 2) + b) * 2^m = ((val_int - 2^m) / 2) + ((b + 1) / 2) * 2^m)
     *
     * where
     *
     * val_int = u.tmp
     * b = exponent bias
     * m = number of mantissa bits
     *
     * .
     */

    u.tmp -= 1 << 23; /* Subtract 2^m. */
    u.tmp >>= 1; /* Divide by 2. */
    u.tmp += 1 << 29; /* Add ((b + 1) / 2) * 2^m. */

    return u.f;
}

但在我的 Core 2 Duo Pentium CPU 上,它们似乎并不比 x87 FPU FSQRT 指令更快。看看它们的工作速度是否比您平台上的标准 sqrtf()/sqrt() 更快,以及准确性是否足够。

About the only thing that can be improved here is the square root calculation function.

I've tried these two functions (found in a Wikipedia article on square root computation) to calculate approximate square root values:

float fsqrt(float x)
{
  float xhalf = 0.5f * x;
  union
  {
    float x;
    int i;
  } u;

  u.x = x;
  u.i = 0x5f3759df - (u.i >> 1);
  x *= u.x * (1.5f - xhalf * u.x * u.x);

  return x;
}

float fsqrt2(float z)
{
    union
    {
        int tmp;
        float f;
    } u;

    u.f = z;

    /*
     * To justify the following code, prove that
     *
     * ((((val_int / 2^m) - b) / 2) + b) * 2^m = ((val_int - 2^m) / 2) + ((b + 1) / 2) * 2^m)
     *
     * where
     *
     * val_int = u.tmp
     * b = exponent bias
     * m = number of mantissa bits
     *
     * .
     */

    u.tmp -= 1 << 23; /* Subtract 2^m. */
    u.tmp >>= 1; /* Divide by 2. */
    u.tmp += 1 << 29; /* Add ((b + 1) / 2) * 2^m. */

    return u.f;
}

But on my Core 2 Duo Pentium CPU they don't seem to be faster than the x87 FPU FSQRT instruction. See if they work faster than the standard sqrtf()/sqrt() on your platform and if the accuracy is sufficient.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文