计算相对角度的两个函数

有时候需要计算点点之间的相对角度,使用arctan等需要考虑符号问题,而且比较慢,如果只需要用来比较或排序,可以完全不用计算精确大小。

下面是两个函数,可以完美解决,返回值是单调的~~

pseudoangle

// Returns the pseudoangle between the line p1 to (infinity, p1.y) 
// and the line from p1 to p2. The pseudoangle has the property 
// that the ordering of points by true angle anround p1 and 
// ordering of points by pseudoangle are the same The result is
// in the range [0, 4) (or error -1). 
float pseudoangle(const WPoint& p1, const WPoint& p2) {
   WVector delta = p2 - p1;
   float result;
   
   if ((delta.x == 0) && (delta.y == 0)) {
      return -1;
   } else {
      result =(float) (delta.y / (abs(delta.x) + abs(delta.y)));
      if (delta.x < 0.0) {
         result = 2.0f - result;
      } else {
         result = 4.0f + result;
      }
   }
   return result;
}

Fowler Angles

from: http://paulbourke.net/geometry/fowler/

/*
   This function is due to Rob Fowler.  Given dy and dx between 2 points
   A and B, we calculate a number in [0.0, 8.0) which is a monotonic
   function of the direction from A to B. 

   (0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0) correspond to
   (  0,  45,  90, 135, 180, 225, 270, 315, 360) degrees, measured
   counter-clockwise from the positive x axis.
*/
double FowlerAngle(dy,dx)
double dy,dx;
{
    double adx, ady;    /* Absolute Values of Dx and Dy */
    int    code;        /* Angular Region Classification Code */

    adx = (dx < 0) ? -dx : dx;  /* Compute the absolute values. */
    ady = (dy < 0) ? -dy : dy;

    code = (adx < ady) ? 1 : 0;
    if (dx < 0)  code += 2;
    if (dy < 0)  code += 4;

    switch (code)
    {
        case 0: return (dx==0) ? 0 : ady/adx;  /* [  0, 45] */
        case 1: return (2.0 - (adx/ady));      /* ( 45, 90] */
        case 3: return (2.0 + (adx/ady));      /* ( 90,135) */
        case 2: return (4.0 - (ady/adx));      /* [135,180] */
        case 6: return (4.0 + (ady/adx));      /* (180,225] */
        case 7: return (6.0 - (adx/ady));      /* (225,270) */
        case 5: return (6.0 + (adx/ady));      /* [270,315) */
        case 4: return (8.0 - (ady/adx));      /* [315,360) */
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值