首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

已知一个点的坐标,怎么判断该点是否在某扇形里面

2012-06-23 
已知一个点的坐标,如何判断该点是否在某扇形里面。先插图 平均分成8份。从0开始,每份45。 如何判断改点在哪个

已知一个点的坐标,如何判断该点是否在某扇形里面。
先插图


平均分成8份。从0°开始,每份45°。 如何判断改点在哪个扇形区域里面?(已知点的坐标)。 在线等 急急急·!!!

[解决办法]
按照楼主的题意,随手写了一段:

C/C++ code
#include<iostream>#include<math.h>#define PI 3.1415926    //宏定义PI,意图是:一个圆周率的近似值。using namespace std;int whichSector(double X, double Y, double R) {    double mod;    mod = sqrt(X * X + Y * Y); //将点(X,Y)视为复平面上的点,与复数一一对应,现求复数的模。    double arg;    arg = atan2(Y, X); //求复数的辐角。    if (mod > R) { //如果复数的模大于预设的半径,则返回0。        return 0;    } else { //根据复数的辐角来判别该点落在那个扇区。        if (arg > (double) (0.0 * PI / 4.0)                && arg < (double) (1.0 * PI / 4.0)) {            return 1;        }        if (arg > (double) (1.0 * PI / 4.0)                && arg < (double) (2.0 * PI / 4.0)) {            return 2;        }        if (arg > (double) (2.0 * PI / 4.0)                && arg < (double) (3.0 * PI / 4.0)) {            return 3;        }        if (arg > (double) (3.0 * PI / 4.0)                && arg < (double) (4.0 * PI / 4.0)) {            return 4;        }        if (arg > (double) (-4.0 * PI / 4.0)                && arg < (double) (-3.0 * PI / 4.0)) {            return 5;        }        if (arg > (double) (-3.0 * PI / 4.0)                && arg < (double) (-2.0 * PI / 4.0)) {            return 6;        }        if (arg > (double) (-2.0 * PI / 4.0)                && arg < (double) (-1.0 * PI / 4.0)) {            return 7;        }        if (arg > (double) (-1.0 * PI / 4.0)                && arg < (double) (-0.0 * PI / 4.0)) {            return 8;        }        return 999; //这是几率极低的事件。    }    return 0;}int main(void) {    double r, x, y;    cout << "Please tell me the Radius of your Circle:" << endl;    cin >> r;    cout << "Please tell me the value of X of your Point:" << endl;    cin >> x;    cout << "Please tell me the value of Y of your Point:" << endl;    cin >> y;    int w;    w = whichSector(x, y, r);    if (0 == w) {        cout << "Your point is OUT of your Circle!" << endl;        return 0;    } else {        if (999 == w) {            cout                    << "Oops... Your Point is ***critically*** ON a border that belongs to no sector!"                    << endl;        } else {            cout << "Your Point is ON a certain area of the sector #" << w                    << "." << endl;        }    }    return 0;}
[解决办法]
为了解决上述的“信息丢失”问题,我们必须找到一种信息不会丢失的等价变换。

在数学里面,实现这种等价变换的工具已经有了,那就是复数vs复平面(上的点)。

任何平面上的点(不论是用直角坐标系刻画,还是用极坐标系刻画),都等价于复平面上的点。

那么,我们可以把楼主的题目中的自由点A(xA,yA)视为复平面上的点。

根据高斯(C.F.Gauss)的原则,复平面上的点与复数是一一对应的。

即,自由点A(xA,yA)与复数Z=xA+yAi完全等价。

也即,自由点A的纵横坐标值与复数Z的虚实二部(不是任督二脉)完全等价。

从复数Z的虚实二部,变换为复数的模和辐角,这个过程中信息不会丢失。

而复数的模(mod)和辐角(arg)正是解答本题的关键:

(一)将复数Z的模与预设的圆半径比较大小,可以判别自由点是否超越圆周范围。

(二)根据复数Z的辐角,可以判别自由点落在哪个扇区。

进入C++ 解题:

(一)计算复数Z的模,很简单,纵横坐标值的平方和再开平方。

(二)计算复数Z的辐角,要注意,C++的<math.h>提供的atan反正切函数,只能计算出值域为从-PI/2到PI/2的所谓“主值”,这样不足以匹配8个扇区。所幸的是,<math.h>提供了atan2函数,该函数接受两个double参数即点的纵横二坐标值,可以计算出值域为从-PI到PI的全圆周角值。

上述解法,就是我贴在8楼的代码。

以上,仅供参考,呵呵……


[解决办法]
我在上面提到的解法,虽然完全符合数学原理,但在计算机上运算,却有着致命的缺陷。

那就是:复数可以与实数对一一对应,而实数在数轴上是连续分布的。但是,计算机里的数字,都是以离散形态存在的。

那么,用计算机计算实数,不可避免地,将会有误差,而有些误差会造成定性判断的错误。

之前的解法,在上述问题上的风险,还是比较显著的。

于是,我们要寻找一个更加接近离散性判断的方法。

我们观察到,圆周内部区域,被分割为8个扇区。这8个扇区乃辐射对称且全等。



8等于2的3次方,这意味着,8个离散量必然可以用3个二元离散量的有序排列来一一对应。

二元离散量有3个,这意味着我们在题目中,要找到合适的关于自由点的三个自由度。

对于自由点A(x,y),最合适的三个自由度:

(1)x>0 的真值;
(2)y>0 的真值;
(3)x^2>y^2 的真值(为什么是x和y的平方比较,而不用x>y?请思考一下……)。

可以列出如下真值表:

C/C++ code
+-------+-------+-------+------+-------+--------+|  x>0  |  y>0  |x^2>y^2| Code | dValue| Sector#|+-------+-------+-------+------+-------+--------+|   1   |   1   |   1   |  111 |   7   |    1   |+-------+-------+-------+------+-------+--------+|   1   |   1   |   0   |  110 |   6   |    2   |+-------+-------+-------+------+-------+--------+|   0   |   1   |   0   |  010 |   2   |    3   |+-------+-------+-------+------+-------+--------+|   0   |   1   |   1   |  011 |   3   |    4   |+-------+-------+-------+------+-------+--------+|   0   |   0   |   1   |  001 |   1   |    5   |+-------+-------+-------+------+-------+--------+|   0   |   0   |   0   |  000 |   0   |    6   |+-------+-------+-------+------+-------+--------+|   1   |   0   |   0   |  100 |   4   |    7   |+-------+-------+-------+------+-------+--------+|   1   |   0   |   1   |  101 |   5   |    8   |+-------+-------+-------+------+-------+--------+ 

热点排行