みけCATのにっき(仮)
つれづれなるまゝに、日くらし、PCにむかひて、心に移りゆくよしなし事を、そこはかとなく書きつくれば、あやしうこそものぐるほしけれ。
(本当か!?)
出典

多角形を三角形に分割する

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

多角形を三角形に分割する

投稿記事 by みけCAT » 12年前

多角形を三角形に分割します。
これにより、多角形の面積を求めることもできます。
しかし、最終的な目的は、画像からポリゴンに変換することです。

CODE:

#include 

static const double EPS = 1e-7;

static double calc_square(int x1,int y1,int x2,int y2,int x3,int y3) {
	int vx1,vy1,vx2,vy2;
	double result;
	vx1=x2-x1;vy1=y2-y1;
	vx2=x3-x1;vy2=y3-y1;
	result=vx1*vy2-vx2*vy1;
	if(result0) || (g1213>0 && g12140) || (g3431>0 && g3432=0 && n2123>=0) ||
		(g1214==0 && n1214>=0 && n2124>=0) ||
		(g3431==0 && n3431>=0 && n4341>=0) ||
		(g3432==0 && n3432>=0 && n4342>=0)
	) return 1;

	return 0;
}

static int isInTriangle(int x,int y,int x1,int y1,int x2,int y2,int x3,int y3) {
	int vx1,vy1,vx2,vy2;
	int tvx,tvy;
	int delta;
	double s,t;
	vx1=x2-x1;vy1=y2-y1;
	vx2=x3-x1;vy2=y3-y1;
	tvx=x-x1;tvy=y-y1;
	delta=vx1*vy2-vx2*vy1;
	if(delta==0)return 0;
	s=(double)(vy2*tvx-vx2*tvy)/delta;
	t=(double)(-vy1*tvx+vx1*tvy)/delta;
	return s+EPS>0 && t+EPS>0 && s+t3 && now>=0) {
		//凹んでいない 
		if((x[prev[now]]-x[now])*(y[next[now]]-y[now])-(x[next[now]]-x[now])*(y[prev[now]]-y[now])>=0) {
			//次の点が作ろうとしている三角形の中に入っていない 
			if(!isInTriangle(x[prev[prev[now]]],y[prev[prev[now]]],
					x[now],y[now],x[prev[now]],y[prev[now]],x[next[now]],y[next[now]]) &&
				!isInTriangle(x[next[next[now]]],y[next[next[now]]],
					x[now],y[now],x[prev[now]],y[prev[now]],x[next[now]],y[next[now]])) {
				//線が交わっていない 
				int ok=1;
				for(i=next[next[now]];i!=prev[prev[now]];i=next[i]) {
					if(isCross(x[prev[now]],y[prev[now]],x[next[now]],y[next[now]],
						x[i],y[i],x[next[i]],y[next[i]])){ok=0;break;}
				}
				if(ok) {
					//三角形を作って頂点を外す 
					triangles[triangle_count][0]=now;
					triangles[triangle_count][1]=prev[now];
					triangles[triangle_count][2]=next[now];
					next[prev[now]]=next[now];
					prev[next[now]]=prev[now];
					choten_rest--;
					triangle_count++;
					prev_now=prev[now];
				}
			}
		}
		now=next[now];
		//「一周して頂点が減らない」=無限ループを弾く
		if(now==prev_now)now=-1;
	}
	if(now<0) {
		free(prev);
		free(next);
		return -1;
	}
	//最後の三角形を加える 
	triangles[triangle_count][0]=now;
	triangles[triangle_count][1]=prev[now];
	triangles[triangle_count][2]=next[now];
	triangle_count++;
	//おまけで面積を求める 
	square=0;
	for(i=0;i<triangle_count;i++) {
		square+=calc_square(
			x[triangles[i][0]],y[triangles[i][0]],
			x[triangles[i][1]],y[triangles[i][1]],
			x[triangles[i][2]],y[triangles[i][2]]
		);
	}
	free(prev);
	free(next);
	return square;
}
このプログラムを使うと、
こんな超複雑な図形も
complex.png
超複雑な図形
こんな可愛い図形も
cat.png
可愛い図形
三角形に分割し、面積を求めることができます。
バイナリも添付します。
添付ファイル

[拡張子 zip は無効化されているため、表示できません]


アバター
nullptr
記事: 239
登録日時: 13年前

Re: 多角形を三角形に分割する

投稿記事 by nullptr » 12年前

なかなかハードボイルドな分割の仕方ですね

アバター
MoNoQLoREATOR
記事: 284
登録日時: 14年前

Re: 多角形を三角形に分割する

投稿記事 by MoNoQLoREATOR » 12年前

なるほど~。
しかし、『多角形』でなければならないため、画像をポリゴンに分割するのは難しそうですね。

ISLe
記事: 2650
登録日時: 15年前

Re: 多角形を三角形に分割する

投稿記事 by ISLe » 12年前

分割線が放射状に伸びてるあたりメッシュとしては効率悪いのでは。