Loading

计算几何笔记01

01

A

什么是凸包?

NailslnTheTable

PaintBlending

ColorSpace

ConvexHull:所有分量总和为100%且非负。

B

Extremity(极性)

极点(Extreme Point):在一组点中,沿着这个点座直线,必然能找到一条直线,使得其他所有点都在该直线的一侧。

Strategy

将问题转化为如何在所有点中鉴别极点和非极点。

判断一个点是否会被包含于另外三个点所确定的三角形内部。如果是则不是极点。

In-Triangle Test

伪代码:

Mark all points of S as EXTREME

for each triangle \(\Delta (p, q, r)\)

​ for each \(s\in S\\ \{p, q, r\}\)

​ If \(s \in \Delta(p, q, r)\) then

​ mark s as NON_EXTREME

void extremePoint(Point S[], int n)
{
    for(int s = 0; s < n; s++) S[s].extreme = true;
    for(int p = 0; p < n; p++)
        for(int q = p + 1; q < n; q++)
            for(int r = q + 1; r < n; r++)
                for(int s = 0; s < n; s++)
                {
                    if(s == p || s == q || s == r || !S[s].extreme)
                        continue;
                    if(InTriangle(S[p], S[q], S[r], S[s]))
                        S[s].extreme = false;
                }
}

复杂度为\(O(n^4)\)

To-Left Test

如何判定点是否落在三角形内部?

点相对于另外两个点确定的有向线段而言落在左侧还是右侧?

InTriangle(p, q, r, s) iff

​ ToLeft(p, q, s) == ToLeft(q, r, s) == ToLeft(r, p, s) == True

Determinal

利用海伦公式求有向面积,基于行列式进行ToLeft测试。

bool ToLeft(Point p, Point q, Point s)
{
	return Area2(p, q, s) > 0;
}
int Area2(Point p, Point q, Point s)
{
	return p.x * q.y -p.y * q.x
	+ q.x * s.y - q.y * s.x
	+s.x * p.y -s.y * p.x;
}

有效地把运算限制在整数域,避免浮点运算的误差。

C

Definition

Extreme Edge(极边):对凸包有贡献的边。

问题转化为如何甄别任意两点之间连边是否为极边。

Algorithm

伪代码:

For each directed segment pq

​ If points in S{p, q} lie to the same side of pq then

​ Let EE = EE \(\cup\) {pq}

复杂度为\(O(n^3)\)

void markEE(Point S[], int n)
{
	for(int k = 0; k < n; k++)
	{
		S[k].extreme = False;
	}
	for(int p = 0; p < n; p++)
	{
		for(int q = p + 1; q < n; q++)
		{
			checkEdge(S, n, p, q);//有向边pq
		}
	}
}
void checkEdge(Point S[], int n, int p, int q)
{
    bool LEmpty = True, REmpty = True;
    for(int l = 0; k < n && (LEmpty || REmpty); k++)
    {
        if(k != p && k != q)//非端点
        {
            ToLeft(S[p], S[q], S[k]) ? LEmpty = False : REmpty = False;
        }
        if(LEmpty || REmpty)
        {
            S[p].extreme = S[q].extreme = True;
        }
    }
}

posted @ 2020-08-06 20:47  脂环  阅读(192)  评论(0编辑  收藏  举报