Counter-Clockwise 三点位置关系 计算几何学

本文探讨了通过向量积判断点相对于线段的位置,包括逆时针、顺时针、在线段前方、后方或线上,以及如何利用这一原理解决几何问题。

题目链接:https://vjudge.net/problem/Aizu-CGL_1_C

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main()
{
    double x0,y0,x1,y1;
    scanf("%lf%lf%lf%lf",&x0,&y0,&x1,&y1);
    int q;
    scanf("%d",&q);
    double x2,y2;
    while(q--)
    {
        scanf("%lf%lf",&x2,&y2);
        double  ans=(x1-x0)*(y2-y0)-(x2-x0)*(y1-y0);
        if(ans>0)
        {
            printf("COUNTER_CLOCKWISE\n");  ///1
        }
        else if(ans<0)
        {
            printf("CLOCKWISE\n");///2
        }
        else
        {
            double ans1=(x1-x0)*(x2-x0)+(y1-y0)*(y2-y0);
            if(ans1<0)
            {
                printf("ONLINE_BACK\n");///3
            }
            else
            {
                double l1=sqrt((x1-x0)*(x1-x0)+(y1-y0)*(y1-y0));
                double l2=sqrt((x2-x0)*(x2-x0)+(y2-y0)*(y2-y0));
                if(l1<l2)
                {
                    printf("ONLINE_FRONT\n");///4
                }
                else printf("ON_SEGMENT\n");///5
            }
        }
    }
}

向量积可以被定义为:
模长:(在这里θ表示两向量之间的夹角(共起点的前提下)(0°≤θ≤180°),它位于这两个矢量所定义的平面上。)
在这里插入图片描述
方向:a向量与b向量的向量积的方向与这两个向量所在平面垂直,且遵守右手定则。(一个简单的确定满足“右手定则”的结果向量的方向的方法是这样的:若坐标系是满足右手定则的,当右手的四指从a以不超过180度的转角转向b时,竖起的大拇指指向是c的方向。)
也可以这样定义(等效):
向量积|c|=|a×b|=|a||b|sin<a,b>
即c的长度在数值上等于以a,b,夹角为θ组成的平行四边形的面积。
而c的方向垂直于a与b所决定的平面,c的指向按右手定则从a转向b来确定。
*运算结果c是一个伪向量。这是因为在不同的坐标系中c可能不同。 [1]

在这里插入图片描述

设 p1=(x1,y1),p2=(x2,y2),p3=(x3,y3)
p12=(x2-x1, y2-y1) p23=(x3-x2, y3-y2)
则当 p12 与 p23 的叉乘(向量积)p12 x p23 = (x2-x1)(y3-y2)-(y2-y1)(x3-x2)
为正时,p1-p2-p3路径的走向为逆时针,
为负时,p1-p2-p3 走向为顺时针,
为零时,p1-p2-p3 所走的方向不变,亦即三点在一直线上。

这段代码定义了一个名为 `Direction` 的 `public enum` 类型,用于表示路径绘制的方向(顺时针或逆时针)。它通常用于图形绘制(如 Android 的 `Path` 类或 Skia 图形库)。 ### 代码解析: 1. **枚举定义** - 定义了两个枚举常量: - `CW`(顺时针,Clockwise),值为 `0`。 - `CCW`(逆时针,Counter-Clockwise),值为 `1`。 - 注释提到,这些值必须与 Skia(`SkPath.h`)中的枚举值匹配,说明这是一个与底层 C++ 图形库交互的 JNI 封装。 2. **构造函数** - `Direction(int ni)` 是一个私有构造函数(枚举的构造函数默认是私有的),接受一个 `int` 参数 `ni`,表示底层 Native 代码使用的整数值。 - 例如: - `CW` 对应 `nativeInt = 0`, - `CCW` 对应 `nativeInt = 1`。 3. **字段 `nativeInt`** - 这是一个 `final int` 字段,存储与 Native 代码对应的整数值。 - 由于是 `final`,枚举常量一旦创建就不能修改其值。 ### 用途: - 这个枚举通常用于图形路径(如 `Path.addRoundRect()` 或 `Path.setFillType()`)中,指定绘制方向。 - 例如,在 Android 的 `Path` 类中,`addRoundRect()` 方法的最后一个参数就是 `Direction`,用于控制圆角矩形的绘制方向。 ### 潜在问题: 1. **硬编码 Native 值** - 如果 Skia 的 `SkPath.h` 中的枚举值发生变化,这里的 `nativeInt` 需要同步修改,否则会导致 JNI 调用错误。 - 建议通过单元测试验证 Native 值的正确性。 2. **扩展性** - 由于枚举值是固定的(`CW` 和 `CCW`),如果未来需要支持其他方向(如双向路径),可能需要扩展。 ### 改进建议: 如果这是一个与 Native 代码交互的枚举,可以添加一个静态方法,通过 Native 值反向获取枚举: ```java public static Direction fromNativeInt(int nativeInt) { for (Direction dir : values()) { if (dir.nativeInt == nativeInt) { return dir; } } throw new IllegalArgumentException("Unknown nativeInt: " + nativeInt); } ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值