1.判断点在三角形的内外
即可判定点P在
内。
三角形面积计算公式:.
2.判断点在多边形的内外
方法一:扫描法
以p点做一条射线,让其与多边形一个顶点相交,再判断是否与多边形上点共线当然这个点不可能是顶点,就是说作一条射线,与多边形相交一点就认为在里面,相交0或偶数点就在外面(仔细想想为什么偶数点就一定可以)。
#include<iostream>
#include<string>
#include<sstream>
#include<set>
#include<algorithm>
#include<vector>
#include<map>
using namespace std;
#define eps 1.0e-5
inline double max(double a, double b) { return a > b ? a : b; }
inline double min(double a, double b) { return a < b ? a : b; }
inline double dabs(double a) { return a <0 ? -a : a; }
struct Point {
double x, y;
};
Point poly[110];
int n, m;
bool online(const Point& p1, const Point& p2, const Point& p3) {//判断是否共线
if (p2.x >= min(p1.x, p3.x) && p2.x <= max(p1.x, p3.x) && p2.y >= min(p1.y, p3.y) && p2.y <= max(p1.y, p3.y)) {
if (dabs((p2.x - p1.x)*(p3.y - p1.y) - (p3.x - p1.x)*(p2.y - p1.y)) <= eps)return true;
}
return false;
}
bool insidepolygon(Point p) {
int counter = 0;
double xinters;
Point p1, p2;
p1 = poly[0];
for (int i = 1; i <= n; i++) {
p2 = poly[i%n];
if (online(p1, p, p2))return true;
if (p.y > min(p1.y, p2.y)&& p.y <= max(p1.y, p2.y)&& p.x <= max(p1.x, p2.x)) {
if (p1.y != p2.y) {
xinters = (p.y - p1.y)*(p2.x - p1.x) / (p2.y - p1.y) + p1.x;
if (p1.x == p2.x || p.x <= xinters)counter++;//说明射线与顶点之外的的相交
}
}
p1 = p2;
}
if (counter % 2 == 0)return false;
return true;
}
int main() {
int t = 0;
Point p;
while (cin >> n&&n) {
cin >> m;
for (int i = 0; i < n; i++)
cin >> poly[i].x >> poly[i].y;
for (int i = 0; i < m; i++) {
cin >> p.x >> p.y;
if (insidepolygon(p))
cout << "Within" << endl;
else
cout << "Outside" << endl;
}
}
return 0;
}
方法二:叉乘判别法(只适用于凸边形)
连接要测试的点p与第一个顶点为向量v,连接第一个顶点与第二个顶点为向量u,都以第一个顶点为起点,u和v做叉乘,从第二条边开始判断上一个结果*当前是否小于0,小于0就在外面。
struct Point {
double x, y;
};
double multi(Point p1, Point p2, Point p0) {
return (p1.x - p0.x)*(p2.y - p0.y) - (p2.x - p0.x)*(p1.y - p0.y);
}
Point edge[100][2];//记录边,起点和终点
int isInside(Point p, Point edge[][2], int n) {
int i;
double pre;
double now;
for (i = 0; i < n; i++) {
now = multi(p, edge[i][1], edge[i][0]);
if (i > 0) {
if (pre*now < 0)//主要是记录方向
return 0;
}
pre = now;
}
return 1;
}
方法三:角度和的判断法(适用任意多边形)
p点到各个顶点边的夹角和为360。
累计交相加就可以了,可以用叉积来求。