点が多角形の外部・内部にあるかの判定 山中和義 2007/12/28 13:12:00
点が多角形の外部・内部にあるかの判定 |
返事を書く ノートメニュー |
山中和義 <drdlxujciw> 2007/12/28 13:12:00 | |
凸多角形の場合(頂点は反時計まわりに定義する)
!●直線の方程式による DEF f(x1,y1,x2,y2, X,Y)=(y1-y2)*(x1-X) + (x1-x2)*(Y-y1) !2点(x1,y1)、(x2,y2)を通る直線 LET N=3 !頂点の数 DIM x(N),y(N) !頂点の位置 ※反時計まわりに定義 LET x(1)=0 !点A LET y(1)=0 LET x(2)=1 !B LET y(2)=0 LET x(3)=1/2 !C LET y(3)=SQR(3)/2 SET WINDOW -1,2, -1,2 !表示領域 DRAW grid !座標 MAT PLOT LINES, LIMIT n: x,y !多角形を表示する PLOT LINES: x(n),y(n); x(1),y(1) !閉じる DO MOUSE POLL mx,my,left,right !P FOR i=1 TO N !各辺に対して IF f(x(i),y(i),x(MOD(i,N)+1),y(MOD(i,N)+1), mx,my)>0 THEN EXIT FOR NEXT i IF i>N THEN PRINT "内部" ELSE PRINT "外部";i LOOP UNTIL right=1 !右クリックで終了する END !●ベクトルによる FUNCTION cross2d(ux,uy, vx,vy) !2Dの擬似外積u×v LET cross2d=uy*vx-ux*vy END FUNCTION LET N=3 !頂点の数 DIM x(N),y(N) !頂点の位置 ※反時計まわりに定義 LET x(1)=0 !点A LET y(1)=0 LET x(2)=1 !B LET y(2)=0 LET x(3)=1/2 !C LET y(3)=SQR(3)/2 SET WINDOW -1,2, -1,2 !表示領域 DRAW grid !座標 MAT PLOT LINES, LIMIT N: x,y !多角形を表示する PLOT LINES: x(N),y(N); x(1),y(1) !閉じる DO MOUSE POLL mx,my,left,right !P FOR i=1 TO N !各辺に対して IF cross2d(mx-x(i),my-y(i),x(MOD(i,N)+1)-x(i),y(MOD(i,N)+1)-y(i))<0 THEN EXIT FOR NEXT i IF i>N THEN PRINT "内部" ELSE PRINT "外部";i LOOP UNTIL right=1 !右クリックで終了する END !●行列式による !2点(x1,y1)、(x2,y2)を通る直線Lの陰関数形式 !L(X,Y)=│x1 y1 1│=│x1-X y1-Y│ ! │x2 y2 1│ │x2-X y2-Y│ ! │X Y 1│ FUNCTION orient2d(x1,y1,x2,y2, x,y) !直線との位置判定 DIM L(2,2) LET L(1,1)=x1-x LET L(1,2)=y1-y LET L(2,1)=x2-x LET L(2,2)=y2-y LET orient2d=DET(L) !DIM L(3,3) !LET L(1,1)=x1 !LET L(1,2)=y1 !LET L(1,3)=1 !LET L(2,1)=x2 !LET L(2,2)=y2 !LET L(2,3)=1 !LET L(3,1)=x !LET L(3,2)=y !LET L(3,3)=1 !LET orient2d=DET(L) !正なら左側、負なら右側 END FUNCTION LET N=3 !頂点の数 DIM x(N),y(N) !頂点の位置 ※反時計まわりに定義 LET x(1)=0 !点A LET y(1)=0 LET x(2)=1 !B LET y(2)=0 LET x(3)=1/2 !C LET y(3)=SQR(3)/2 SET WINDOW -1,2, -1,2 !表示領域 DRAW grid !座標 MAT PLOT LINES, LIMIT n: x,y !多角形を表示する PLOT LINES: x(n),y(n); x(1),y(1) !閉じる DO MOUSE POLL mx,my,left,right !P FOR i=1 TO N !各辺に対して IF orient2d(x(i),y(i),x(MOD(i,N)+1),y(MOD(i,N)+1), mx,my)<0 THEN EXIT FOR NEXT i IF i>N THEN PRINT "内部" ELSE PRINT "外部";i LOOP UNTIL right=1 !右クリックで終了する END |
└つづき 山中和義 2007/12/28 19:06:51