代码说明:
1. 根据点与直线的关系,确定点是否在四边形内;
2. 根据点与圆中心点的距离,确定点是否在圆内;
3. 使用opencv进行显示说明;(当然,如果使用opencv的mask,很容易就能判断出点是否在四边形或者圆内部)
#include <iostream>
#include <opencv2\opencv.hpp>
using namespace std;
using namespace cv;
struct pointLoc
{
float x;
float y;
};
//创建随机数据
void randData(int num, vector<pointLoc> &randomData)
{
randomData.clear();
pointLoc p;
srand((unsigned)time(NULL));
for (int n = 0; n < num; n++)
{
p.x = (int)100 * rand() / (RAND_MAX + 1);
p.y = (int)200 * rand() / (RAND_MAX + 1);
randomData.push_back(p);
}
}
// 定义直线参数结构体
struct LinePara
{
float a;
float b;
float c;//变量满足等式ax + by + c = 0
};
// 获取直线参数
void getLinePara(pointLoc p1, pointLoc p2, LinePara & LP)
{
LP.a = p2.y - p1.y;
LP.b = p1.x - p2.x;
LP.c = p1.y * (p2.x - p1.x) - p1.x * (p2.y - p1.y);
}
/*
假如有第三个点p3(x3,y3)则判断p3与直线的位置关系可以按一下算法:
将p3(x3,y3)带入到直线AX+BY+C=0{A=y2-y1;B=x1-x2;C=y1*(x2-x1)-x1*(y2-y1)}中
如果A*x3+B*y3+C=0则表示点p3(x3,y3)在直线上。
如果A*x3+B*y3+C>0则表示点p3(x3,y3)在直线右侧。
如果A*x3+B*y3+C<0则表示点p3(x3,y3)在直线左侧。
*/
float eval(LinePara LP, pointLoc p)
{
return (LP.a * p.x + LP.b * p.y + LP.c);
}
int main()
{
vector<pointLoc> randomData;
randData(50, randomData);
/*自定义四边形的四个顶点
a—b
| |
d—c
*/
pointLoc p_a, p_b, p_c, p_d;
p_a.x = 20;
p_a.y = 20;
p_b.x = 80;
p_b.y = 20;
p_d.x = 19;
p_d.y = 80;
p_c.x = 81;
p_c.y = 81;
LinePara line_a2b;
getLinePara(p_a, p_b, line_a2b);
LinePara line_b2c;
getLinePara(p_b, p_c, line_b2c);
LinePara line_c2d;
getLinePara(p_c, p_d, line_c2d);
LinePara line_d2a;
getLinePara(p_d, p_a, line_d2a);
//求在四边形内的点
vector<pointLoc> pInPolygon;
pInPolygon.clear();
for (int m = 0; m < randomData.size(); m++)
{
float df = eval(line_a2b, randomData[m]);
if (df > 0)
continue;
df = eval(line_b2c, randomData[m]);
if (df > 0)
continue;
df = eval(line_c2d, randomData[m]);
if (df > 0)
continue;
df = eval(line_d2a, randomData[m]);
if (df > 0)
continue;
pInPolygon.push_back(randomData[m]);
}
//求在圆内的点
Point centerP(50, 150);
int raduis = 30;
vector<pointLoc> pInCircle;
pInCircle.clear();
for (int m = 0; m < randomData.size(); m++)
{
if (sqrt(pow(randomData[m].x - centerP.x, 2) + pow(randomData[m].y - centerP.y, 2)) > raduis)
continue;
pInCircle.push_back(randomData[m]);
}
//显示结果
cv::Mat xx = cv::Mat::zeros(200, 100, CV_8UC3);
line(xx, Point(p_a.x, p_a.y), Point(p_b.x, p_b.y), Scalar(0, 255, 0));
line(xx, Point(p_b.x, p_b.y), Point(p_c.x, p_c.y), Scalar(0, 255, 0));
line(xx, Point(p_c.x, p_c.y), Point(p_d.x, p_d.y), Scalar(0, 255, 0));
line(xx, Point(p_d.x, p_d.y), Point(p_a.x, p_a.y), Scalar(0, 255, 0));
circle(xx, centerP, raduis, Scalar(0, 255, 0));
for (int m = 0; m < randomData.size(); m++)
{
xx.at<Vec3b>(randomData[m].y, randomData[m].x)[0] = 255;
xx.at<Vec3b>(randomData[m].y, randomData[m].x)[1] = 0;
xx.at<Vec3b>(randomData[m].y, randomData[m].x)[2] = 0;
}
for (int m = 0; m < pInPolygon.size(); m++)
{
xx.at<Vec3b>(pInPolygon[m].y, pInPolygon[m].x)[0] = 0;
xx.at<Vec3b>(pInPolygon[m].y, pInPolygon[m].x)[1] = 0;
xx.at<Vec3b>(pInPolygon[m].y, pInPolygon[m].x)[2] = 255;
}
for (int m = 0; m < pInCircle.size(); m++)
{
xx.at<Vec3b>(pInCircle[m].y, pInCircle[m].x)[0] = 0;
xx.at<Vec3b>(pInCircle[m].y, pInCircle[m].x)[1] = 255;
xx.at<Vec3b>(pInCircle[m].y, pInCircle[m].x)[2] = 255;
}
}