点と線

[pukiwiki]
今年は松本清張イヤーだったみたいですけれども~  普通に幾何の話。
GIS関係で必要になったので調べたことをメモ。

直線と点の距離の求め方、などなど。
[/pukiwiki]

[pukiwiki]

-平面上に任意の点Pと、一本の線分Lを置き
-点Pから線分Lへ垂線を下ろす。
-垂線とLの交点Cを求めよ
–ついでに、PとLの距離が一定以下かどうか、L上に交点が存在するかどうかもチェック

既存のプロットツールが使いにくかったので自分で小さなスクリプトを書くことに。。。。以下、アルゴリズムの検算用のショートプログラムなどなど

*[[点の直線への正射影:http://amath.doshisha.ac.jp/~kon/lectures/2007.linear-algebra-I/html.dir/node27.html]]
この証明がわかりやすかったですー。要点だけメモしておくと

“原点を通る、向きが ベクトル e (ex, ey,ez)  (長さは1) の直線へ
任意の点 P (px,py,pz)すなわち、原点からのベクトルPで表される点から
垂線を下ろしたときの交点C は
C=(e・p)*e
-ベクトルeを、
-ベクトルeとベクトルPの内積倍したものとなる

“平面状の線分ABへの垂線を考える場合、
A (またはB) および、点Pを原点へと平行移動して、
交点を求めてから、もう一度元の位置に戻してやればよい
*3次元の二直線間の最短距離
-[[その1:http://ahirujigen.hp.infoseek.co.jp/coding002.html]]
-[[その2:http://marupeke296.com/COL_Basic_No2_ShortTec.html#2%E7%9B%B4%E7%B7%9A%E3%81%AE%E6%9C%80%E7%9F%AD%E8%B7%9D%E9%9B%A2]]
こちらは、また今度
距離がゼロとなるときを考えれば、二直線の交点を求められる、かな?

—-
というわけで、上記でホントにいいのかチェック
http://boxheadroom.com/wp/wp-content/uploads/2009/12/point_and_line.gif

-黒い実線が線分L。  点Pをいくつかとって、垂線を降ろしています。
-線分Lの両側に青い線を引き、それよりも内側ならば青で垂線を引く
遠ければ緑の垂線
-線分との交点がなければ、延長線上に赤色で垂線を引く

[/pukiwiki]

import Image,ImageDraw
import random,math


W,H=1024,768
im=Image.new("RGB",(W,H))
draw=ImageDraw.ImageDraw(im)

draw.rectangle((0,0,W,H),0xffffff)

lines=[ (random.randint(0,W),random.randint(0,H),
         random.randint(0,W),random.randint(0,H)) for i in xrange(1)]

points=[ (random.randint(0,W),random.randint(0,H)) for i in xrange(10)]
m=64
for i in lines:
    x0,y0,x1,y1=i
    dx,dy=(x1-x0,y1-y0)
    l=math.sqrt(dx**2+dy**2)
    ex,ey=(dx/l,dy/l)
    draw.line((x0,y0,x1,y1),(0,0,0))
    draw.line((x0+ey*m,y0-ex*m,x1+ey*m,y1-ex*m),(0,0,255))
    draw.line((x0-ey*m,y0+ex*m,x1-ey*m,y1+ex*m),(0,0,255))
    
    for p in points :
        px,py=p
        px2,py2=(px-x0,py-y0)
        a=ex*px2+ey*py2
        cx,cy=(a*ex+x0,a*ey+y0)
        dx2=cx-px
        dy2=cy-py
        l2=math.sqrt(dx2**2+dy2**2)
        
        #print px,py,cx,cy
        if  0<a<l :
            if l2<64:
                col=(0,0,255)
            else :
                col=(0,255,0)
        else :
            col =(255,0,0)
        draw.line((px,py,cx,cy),col)
im.save("test.png")

コメントを残す

メールアドレスが公開されることはありません。