判断向量之间的方向关系,可以使用叉乘、点乘来判断。

点与向量之间的关系

如图所示,展现了点与向量之间的五种关系(相同除外)

对于第一、二种情况,可以用叉乘来判断向量之间的关系。

当叉乘等于零的时候,可以用点乘来判断关系。点乘为负数则是第三种情况,点乘为正,则通过向量的模长来判断。

题目:CGL_1_C

代码:

#include <iostream>
#include <math.h>
using namespace std;

#define COUNTER_CLOCKWISE 1
#define CLOCKWISE 2
#define ONLINE_BACK 3
#define ONLINE_FRONT 4
#define ON_SEGMENT 5

#define EPS 1E-8

class Point
{
public:
    double x, y;
    Point()
    {
    }
    Point(double x, double y)
    {
        (*this).x = x;
        (*this).y = y;
    }

    double operator^(const Point &p) const //叉乘
    {
        return x * p.y - y * p.x;
    }

    double operator*(const Point &p) const //点乘
    {
        return x * p.x + y * p.y;
    }

    Point operator*(const double &d) const
    {
        return Point(x * d, y * d);
    }

    Point operator/(const double &d) const
    {
        return Point(x / d, y / d);
    }

    Point operator-(const Point &p) const
    {
        return Point(x - p.x, y - p.y);
    }

    Point operator+(const Point &p) const
    {
        return Point(x + p.x, y + p.y);
    }

    double sqr()
    {
        return x * x + y * y;
    }
    double abs()
    {
        return sqrt(sqr());
    }

    double distance(const Point &p)
    {
        return fabs((*this - p).abs());
    }

    /*
    void print()
    {

        printf("%.10lf %.10lf\n", x, y);
    }
    */
};

class Line
{
public:
    Point p1, p2;
    Line();
    Line(Point p1, Point p2)
    {
        (*this).p1 = p1;
        (*this).p2 = p2;
    }
};

int ccw(Point p[])
{
    Point vec1 = p[1] - p[0];
    Point vec2 = p[2] - p[0];

    if ((vec1 ^ vec2) > EPS)
        return COUNTER_CLOCKWISE; //p0、p1、p2逆时针
    else if ((vec1 ^ vec2) < -EPS)
        return CLOCKWISE; //p0 p1 p2顺时针
    else                  //p0 p1 p2在一条线上
    {
        if (vec1 * vec2 < -EPS)
            return ONLINE_BACK;
        else
        {
            if (vec1.abs() - vec2.abs() < -EPS)
                return ONLINE_FRONT;
            else
                return ON_SEGMENT;
        }
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    Point p[3];
    for (int i = 0; i < 2; ++i)
    {
        cin >> p[i].x >> p[i].y;
    }

    int q;
    cin >> q;

    while (q--)
    {
        cin >> p[2].x >> p[2].y;
        int ans = ccw(p);
        switch (ans)
        {
        case COUNTER_CLOCKWISE:
            cout << "COUNTER_CLOCKWISE" << endl;
            break;
        case CLOCKWISE:
            cout << "CLOCKWISE" << endl;
            break;
        case ONLINE_FRONT:
            cout << "ONLINE_FRONT" << endl;
            break;
        case ONLINE_BACK:
            cout << "ONLINE_BACK" << endl;
            break;
        case ON_SEGMENT:
            cout << "ON_SEGMENT" << endl;
            break;
        }
    }
}

转载请注明来源:https://www.longjin666.top/?p=782

欢迎关注我的公众号“灯珑”,让我们一起了解更多的事物~

你也可能喜欢

发表评论