判定一个点在平面几何体内部的方法
来源:互联网 发布:淘淘搜软件 编辑:程序博客网 时间:2024/05/17 08:36
判定一个点在平面几何体内部的方法
本文给出了判断一个点在椭圆、多边形(可以是凹边形)、矩形内部的解析方法
所有断定方法为: BOOL Contains(int x, int y), 代码为C++
一、椭园(也适用于园)
P1(x1, y1), P2(x2, y2) 定义椭园外接矩形(左上点与右下点)
CEllipse::CEllipse(int x1, int y1, int x2, int y2)
{
this->x1 = x1<x2?x1:x2;
this->y1 = y1<y2?y1:y2;
this->x2 = x2>=x1?x2:x1;
this->y2 = y2>=y1?y2:y1;
}
BOOL CEllipse::Contains(int x, int y) const
{
if (x < x1 || x > x2 || y < y1 || y > y2)
return FALSE;
// 椭圆的中心
int x0 = x1 + (x2 - x1)/2;
int y0 = y1 + (y2 - y1)/2;
// 平移变换
x -= x0;
y -= y0;
// 长/短半轴
int a = (x0 - x1);
int b = (y0 - y1);
BOOL r = FALSE;
if (a < b)
{
int tmp = a;
a = b; b = tmp;
r = TRUE;
}
// a > b > 0
a *= a;
b *= b;
x *= x;
y *= y;
if (r)
{
return x*a + y*b < a*b;
}
else
{
return x*b + y*a < a*b;
}
}
二、多边形(代码来自SUN JDK1.4)
#define MAX(x, y) (x > y? x: y)
#define MIN(x, y) (x < y? x: y)
CPolygon::CPolygon()
{
xpoints = new int[4];
ypoints = new int[4];
npoints = 4;
memset(xpoints, 0, sizeof(int)*4);
memset(ypoints, 0, sizeof(int)*4);
bounds = NULL;
CalculateBounds(xpoints, ypoints, npoints);
}
CPolygon::CPolygon(const int *xpoints, const int *ypoints, int points)
{
this->xpoints = new int[points];
this->ypoints = new int[points];
bounds = NULL;
memcpy(this->xpoints, xpoints, sizeof(int)*points);
memcpy(this->ypoints, ypoints, sizeof(int)*points);
this->npoints = points;
calculateBounds(this->xpoints, this->ypoints, points);
}
void CPolygon::CalculateBounds(int xpoints[], int ypoints[], int npoints)
{
int boundsMinX = 0x7fffffff;
int boundsMinY = 0x7fffffff;
int boundsMaxX = -1 * 0x7fffffff;
int boundsMaxY = -1 * 0x7fffffff;
for (int i = 0; i < npoints; i++)
{
int x = xpoints[i];
boundsMinX = MIN(boundsMinX, x);
boundsMaxX = MAX(boundsMaxX, x);
int y = ypoints[i];
boundsMinY = MIN(boundsMinY, y);
boundsMaxY = MAX(boundsMaxY, y);
}
bounds = new CRectangle(boundsMinX, boundsMinY,
boundsMaxX - boundsMinX,
boundsMaxY - boundsMinY);
}
CRectangle* CPolygon::GetBoundingBox() const
{
if (npoints == 0)
{
return NULL;
}
return bounds;
}
BOOL CPolygon::Contains(int x, int y) const
{
if (npoints <= 2 || !GetBoundingBox()->Contains(x, y))
{
return FALSE;
}
int hits = 0;
int lastx = xpoints[npoints - 1];
int lasty = ypoints[npoints - 1];
int curx, cury;
// Walk the edges of the polygon
for (int i = 0; i < npoints; lastx = curx, lasty = cury, i++)
{
curx = xpoints[i];
cury = ypoints[i];
if (cury == lasty)
{
continue;
}
int leftx;
if (curx < lastx)
{
if (x >= lastx)
{
continue;
}
leftx = curx;
}
else
{
if (x >= curx)
{
continue;
}
leftx = lastx;
}
double test1, test2;
if (cury < lasty)
{
if (y < cury || y >= lasty)
{
continue;
}
if (x < leftx)
{
hits++;
continue;
}
test1 = x - curx;
test2 = y - cury;
}
else
{
if (y < lasty || y >= cury)
{
continue;
}
if (x < leftx)
{
hits++;
continue;
}
test1 = x - lastx;
test2 = y - lasty;
}
if (test1 < (test2 / (lasty - cury) * (lastx - curx)))
{
hits++;
}
}
return ((hits & 1) != 0);
}
三、矩形
该类有四个属性:左上顶点(x,y),高度(height)与宽度(width)
CRectangle::CRectangle()
{
Init(0, 0, 0, 0);
}
CRectangle::CRectangle(RECT *rect)
{
Init(rect->left, rect->top, rect->right - rect->left + 1, rect->bottom - rect->top + 1);
}
void CRectangle::Init(int x, int y, int width, int height)
{
this->x = x;
this->y = y;
this->width = width;
this->height = height;
}
CRectangle::CRectangle(int x, int y, int width, int height)
{
init(x, y, width, height);
}
BOOL CRectangle::Contains(int x, int y) const
{
return Inside(x, y);
}
BOOL CRectangle::Inside(int X, int Y) const
{
int x2 = x + width - 1;
int y2 = y + height - 1;
int x1 = x <= x2? x:x2;
int y1 = y <= y2? y:y2;
int x3 = x > x2? x:x2;
int y3 = y > y2? y:y2;
return (X <= x3 && X >= x1 && Y <= y3 && Y >= y1);
}
- 判定一个点在平面几何体内部的方法
- 判定一个点在平面几何体内部的方法
- 判定一个点是否在多边形内部
- 判定一个点是否在三角形内部
- 检测二维平面内一个点在多边形内的方法
- 一个点是否在不规则图形内的判定
- 二维平面上点与线段关系的判定
- openGl学习之判定点在三角形的内部还是外部
- 在平面中,一个点绕任意点旋转θ度后的点的坐标
- 在平面中,一个点绕任意点旋转θ度后的点的坐标
- 判定一个点是否在三角形内
- 判定一个点是否在三角形内
- 判定一个点是否在三角形内
- hdu 1756 Cupid's Arrow 点在多边形内部判定
- 输出一个平面点的对称点
- 判断一个点是否在一个复杂多边形的内部
- 在一个二维平面上找到离固定点最近的k个点位置
- 判断一个点是否在多边形内部的问题
- 创意思维:创意导航
- 创意思维:可爱的标头导航
- 创意思维:卡通风格标头导航
- 用户体验设计师的职责
- 一点感想
- 判定一个点在平面几何体内部的方法
- c#学习读书笔记《1》
- 科学与迷信
- 华为面试题算什么,这个背会了外企随便进(1)
- 华为面试题算什么,这个背会了外企随便进(2)
- 好久没来了
- 华为面试题算什么,这个背会了外企随便进(3)
- 华为面试题算什么,这个背会了外企随便进(4)
- xacc.ide v0.1.3.14 by xacc team