- 久しぶりに外部変形を作ろうとしたんだけどニ直線の交点の求め方を忘れてたので覚え書きとしてまとめてみる
説明 | 式 |
---|
直線の方程式 | $$ ax + by + c = 0 $$ |
変形 | $$ ax + by = -c $$ |
両辺を -c で割る | $$ -\frac{a}{c}x – \frac{b}{c}y = 1 $$ |
定数を変更 | $$ a_{1}x + a_{2}y = 1 ( a_{1}=-\frac{a}{c} 、 a_{2}=-\frac{b}{c} )$$ |
$$点 (x_{1},y_{1}) が直線上にある$$ | $$ a_{1}x_{1} + a_{2}y_{1} = 1 $$ |
$$点 (x_{2},y_{2}) が直線上にある$$ | $$ a_{1}x_{2} + a_{2}y_{2} = 1 $$ |
連立方程式を行列にする | $$ \begin{equation}\begin{pmatrix}x_{1} & y_{1} \\x_{2} & y_{2} \end{pmatrix}\begin{pmatrix}a_{1} \\ a_{2}\end{pmatrix}=\begin{pmatrix} 1 \\ 1 \end{pmatrix}\end{equation} $$ |
逆行列をかける | $$ \begin{equation}\begin{pmatrix}a_{1} \\ a_{2}\end{pmatrix}=\begin{pmatrix}x_{1} & y_{1} \\x_{2} & y_{2} \end{pmatrix}^{-1}\begin{pmatrix} 1 \\ 1 \end{pmatrix}\end{equation} $$ |
ニ直線の交点
説明 | 式 |
---|
直線1 | $$ a_{11}x + a_{12}y= 1 $$ |
直線2 | $$ a_{21}x + a_{22}y= 1 $$ |
連立方程式を行列にする | $$ \begin{equation}\begin{pmatrix}a_{11} & a_{12} \\a_{21} & a_{22} \end{pmatrix}\begin{pmatrix}x \\ y\end{pmatrix}=\begin{pmatrix} 1 \\ 1 \end{pmatrix}\end{equation} $$ |
逆行列をかける | $$ \begin{equation}\begin{pmatrix}x \\ y\end{pmatrix}=\begin{pmatrix}a_{11} & a_{12} \\a_{21} & a_{22} \end{pmatrix}^{-1}\begin{pmatrix} 1 \\ 1 \end{pmatrix}\end{equation} $$ |
- ruby 1.8.7 (2010-12-23 patchlevel 330) [i386-mingw32] にて動作確認しています
REM ニ直線の交点を求める.bat
CHCP 932
echo off
REM #jww
REM #cd
goto %EXE
REM #1ln 【一本目の線を選択してください】
REM #2ln 【ニ本目の線を選択してください】
REM #bz
REM #e
:EXE
copy jwc_temp.txt temp.txt
ruby -Ks -x %~f0
GOTO END
REM #~
◎コメント
◎バッチファイル名は自由
◎以下 ruby スクリプト部分
#! ruby
# encoding: SJIS
$stdout=open("jwc_temp.txt","w")
$stderr=open("tmp_err.txt","w")
include Math
require "matrix"
hhp,m1,m2,v0=0,0,0,Vector[1000.0,1000.0]
open("temp.txt").readlines.map{|e|
if %r|^hhp(\d)ln|=~e
hhp=$1.to_i
elsif %r|^ [\d-]|=~e
e=e.split.map{|e| e.to_f}
m1=Matrix[[e[0],e[1]],[e[2],e[3]]] if hhp==1
m2=Matrix[[e[0],e[1]],[e[2],e[3]]] if hhp==2
hhp=0
end}
a1=m1.inv*v0
a2=m2.inv*v0
begin
pt=Matrix[a1.to_a,a2.to_a].inv*v0
rescue
puts "heニ直線が平行です"
exit
end
#線上に乗っているかどうかのチェック
#ベクトルの長さと内積の符号で判断
#線上にある場合の補正を考慮
m1,m2=m1.to_a,m2.to_a
v11,v12=Vector.elements(m1[0]),Vector.elements(m1[1])
v21,v22=Vector.elements(m2[0]),Vector.elements(m2[1])
if (v12-v11).r-(pt-v11).r>-0.1**10 && (v12-v11).inner_product(pt-v11)>-0.1**10 &&
(v22-v21).r-(pt-v21).r>=-0.1**10 && (v22-v21).inner_product(pt-v21)>-0.1**10
puts "pt #{pt[0]} #{pt[1]}"
else
puts "he交点が直線上にありません"
end
__END__
:END
- 出来上がったところで昔考えた外積を使ったバージョンが出てきた
- それもご丁寧に図解付きなんだけど今となっては何をやってるのかよく分からない
REM ニ直線の交点を求める2.bat
CHCP 932
echo off
REM #jww
REM #cd
goto %EXE
REM #1ln 【一本目の線を選択してください】
REM #2ln 【ニ本目の線を選択してください】
REM #bz
REM #e
:EXE
copy jwc_temp.txt temp.txt
ruby -Ks -x %~f0
GOTO END
REM #~
◎コメント
◎バッチファイル名は自由
◎以下 ruby スクリプト部分
#! ruby
# encoding: SJIS
$stdout=open("jwc_temp.txt","w")
$stderr=open("tmp_err.txt","w")
include Math
require "matrix"
hhp,ln1,ln2=0,[],[]
open("temp.txt").readlines.map{|e|
if %r|^hhp(\d)ln|=~e
hhp=$1.to_i
elsif %r|^ [\d-]|=~e
ln1=e.split.map{|e| e.to_f} if hhp==1
ln2=e.split.map{|e| e.to_f} if hhp==2
hhp=0
end}
as=Vector.elements(ln1[0,2]+[0])
bs=Vector.elements(ln2[0,2]+[0])
ae=Vector.elements(ln1[2,2]+[0])
be=Vector.elements(ln2[2,2]+[0])
va=ae-as
vb=be-bs
c1=va.cross(bs-as)
c2=va.cross(be-as)
c3=vb.cross(as-bs)
c4=vb.cross(ae-bs)
d1=c1.r/va.r
d2=c2.r/va.r
pt=bs+(d1/(d1+d2))*vb
if vb.cross(as-bs)==vb.cross(ae-bs) or c1[2]*c2[2]>0 or c3[2]*c4[2]>0
puts "he 交点が求められません"
else
puts "pt #{pt[0]} #{pt[1]}"
end
__END__
:END
- 外部変形自体は役に立たないけどたまに行列とか使うときに毎回悩んでる気がする
- ここまでは準備体操でこれからこの辺を応用して節間線種変更の外部変形を考えてみよう思います
コメント