编程之美 4.4点是否在三角形内

问题:如果一个二维坐标系中,已知三角形三个点的坐标,那么对于任意一点,如何判断其在三角形内呢?(点在三角形边上也算在三角形内)

解法一:面积法

S=Area(ABC)、S1=Area(ABP)、S2=Area(BCP)、S3=Area(CAP)

若P点在三角形内,S=S1+S2+S3

若P在三角形外,S1+S2+S3>S

计算三角形的面积可以使用海伦公式

heron1

而公式里的p为半周长(周长的一半):

heron2

但注意了我们可以利用向量积的几何意义以两个向量为邻边的平行四边形的面积(即三角形面积的2倍)

若 |AB×BP| + |BC×CP| + |CA×AP| = |AB×BC|,则得点 P 在 △ABC 内。

解法二:叉乘法

沿 △ABC 各有向边按一定方向走(顺时针或逆时针),判断点 P 是否在该边的某侧(右侧或左侧),若点 P 在三条边的同侧,则点 P 在 △ABC 内。

分别计算向量 AB、BC、CA 与向量 AP、BP、CP 的向量积(叉乘),若三个结果均同号(正或负,为零表示 P 在边上),则可得点 P 在 △ABC 内。

其中AB = B - A,AB×AP = AB.x*AP.y - AB.y*AP.x即 x1y2-y1x2。

其实不止三角形对于凸多边形也是可以通过叉乘法来判断的。

补充知识:

所谓凸多边形,就是把一个多边形任意一边向两方无限延长成为一条直线,如果多边形的其他各边均在此直线的同旁,那么这个多边形就叫做凸多边形。

下面是示例代码:注意面积法对输入的点序没要求,叉乘法就要按逆时针的顺序。

#include <iostream>
#include <cmath>
using namespace std;

struct point
{
    double x,y;
    point(double _x=0,double _y=0)
    {
        x=_x;
        y=_y;
    }
};

inline double VecProduct(point A,point B,point P)
{
    return (B.x-A.x)*(P.y-A.y)-(B.y-A.y)*(P.x-A.x);
}

double TriArea(point A,point B,point P)
{
    return abs((B.x-A.x)*(P.y-B.y)-(B.y-A.y)*(P.x-B.x));
}

//method:Area
bool isInTriangle1(point A,point B,point C,point P)
{
    double sABP,sBCP,sCAP,sABC;
    sABP=TriArea(A,B,P);
    sBCP=TriArea(B,C,P);
    sCAP=TriArea(C,A,P);
    sABC=TriArea(A,B,C);
    if (sABC==sABP+sBCP+sCAP)
    {
        return true;
    }
    return false;
}
//method:Vector Product,ABC anticlockwise
bool isInTriangle2(point A,point B,point C,point P)
{
    if (VecProduct(A,B,P)>=0 && VecProduct(B,C,P)>=0 && VecProduct(C,A,P)>=0)
    {
        return true;
    }
    return false;
}

void main()
{
    point A(0,2);
    point B(0,0);
    point C(2,0);

    point P1(1,1);//in the Triangle
    point P2(4,4);//outside the Triangle 
    point P3(2,0);//on the edge of the Triangle

    cout<<boolalpha<<isInTriangle1(A,B,C,P1)<<endl;
    cout<<boolalpha<<isInTriangle1(A,B,C,P2)<<endl;
    cout<<boolalpha<<isInTriangle1(A,B,C,P3)<<endl;

    cout<<boolalpha<<isInTriangle2(A,B,C,P1)<<endl;
    cout<<boolalpha<<isInTriangle2(A,B,C,P2)<<endl;
    cout<<boolalpha<<isInTriangle2(A,B,C,P3)<<endl;
}

转载于:https://www.cnblogs.com/Linkabox/p/3357768.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 西门子s7-1200是一种先进的工业控制系统,具有高效、可靠、灵活的特点。它能够为各种工业应用提供完整的自动化解决方案,实现对工艺流程、生产线和机器设备的控制和监控。 《西门子s7-1200系统编程手册v4.4》是一本详尽的系统编程指南,适用于所有使用s7-1200控制器进行编程的人员。本手册包含了控制器硬件、软件和通信方面的基础知识,以及“步骤”、“函数”、“程序”、“块”等编程要素的使用方法和实例应用。 手册中包含许多实用的编程技巧和注意事项,如命名规则、数据类型、数据块管理、趋势图和报警处理等。此外,还介绍了如何使用SIMATIC Manager和TIA Portal软件进行控制器编程和调试,以及如何使用SIMATIC S7-1200工具包和网络通信协议实现数据通信和监控。 阅读本手册可以帮助读者全面掌握s7-1200控制器的编程知识,准确、高效地实现各种自动化控制应用。无论是对于工程师、技术人员,还是对于学习PLC控制系统编程的人群来说,都是一本不可多得的完整参考资料。 ### 回答2: 西门子s7-1200是一款用于工业自动化控制的可编程逻辑控制器。系统编程手册v4.4介绍了该控制器的编程方式和相关的技术细节,包括硬件的结构组成、软件的安装和使用、编程语言的特点和应用、网络和通信的设置等方面。 系统编程手册的内容深入浅出,条理清晰,对于初学者和专业人士都具有很大的参考价值。手册首先介绍了S7-1200的组成结构,包括CPU、I/O模块、通信模块、电源模块等。随后详细介绍了软件的安装过程和编程环境的配置,以及常见的PLC编程语言,如Ladder Diagram、Function Block Diagram、Structured Text等的使用方法和特点。 在网络和通信方面,系统编程手册也提供了大量的参考资料。手册介绍了S7-1200的通信接口和协议,包括TCP/IP、PROFINET、MODBUS、OPC UA等,以及如何配置和使用这些协议实现PLC之间的数据交换和远程控制等功能。 总之,系统编程手册v4.4是一份非常有用的参考资料,对于理解和应用S7-1200控制器具有很大的帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值