点と線



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

直線と点の距離の求め方、などなど。

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

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

点の直線への正射影

この証明がわかりやすかったですー。要点だけメモしておくと

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

  • ベクトルeを、
  • ベクトルeとベクトルPの内積倍したものとなる

平面状の線分ABへの垂線を考える場合、
A (またはB) および、点Pを原点へと平行移動して、
交点を求めてから、もう一度元の位置に戻してやればよい

3次元の二直線間の最短距離

  • その1
  • その2
    こちらは、また今度
    距離がゼロとなるときを考えれば、二直線の交点を求められる、かな?

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

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

Related posts

タグ:

コメントをどうぞ

Comments for this post will be closed on 17 April 2010.