Created on 18.Jun 2013 Modified on 12.Jul 2013 |
指定間隔(秒)による直線(線分)の分割について |
はじめにかつてGIS(地理情報システム)の補助ツールを開発したとき、指定した秒単位で直線(線分)を分割してプロットする必要が生じたのですが、 探し方が悪かったのか、そのロジックを検索しても見つからないことがありました。 仕方がないので文系アラフォーながら渋々と初歩の数学から勉強し直して、そして解法に辿り着いたので、 それをここに紹介いたします。 考え方順を追って説明していきますが、要するにまずベクトルの傾きを求めて、次に大きさの比率を求めたものを乗ずると言うだけです。
通常、地図系に於ける秒はミリ秒で演算されるため。
下記の枠内の線分に注目すると一つのベクトルデータ。すなわち線分となる。
つまり図例のような折れ線は線分の集まりであるのでループ処理で線分を取り出していくこととなる。
プログラムにおいてロジックの単純化がもたらすメリットは計り知れない。
ということで演算を単純化する手法を考えた。 2013/07/12 追記:
単純化しない場合、余弦定理を利用した解決が後段で必要になります。具体的にはベクトル方向をフラグ化し、ベクトル量を絶対値にする。
ベクトルの向きは緯度と経度、それぞれ以下のように2つのフラグで管理できる。
ベクトル量については線分の始点と終点の差分を絶対値で取得すればよい。
なお、ベクトルの大きさにはそもそも符号が付かないので微妙におかしい表現だが、気にしない方向で。
三角比を使うため直角三角形を導出する。
ここまでの処理で始点を0とする1次関数座標が形成されたので、三角形を投影する。
投影した三角形について三平方定理により斜辺(図例では辺b)の長さを求める。
投影した三角形について三辺の長さが求まったので∠CABの角度(Cosθ)を求める。
Cosθ=c/b
傾きは求められたが、前項で求まったのは度数法である。
しかしながら通常の言語では度数法で演算が出来ないため、Cosθを逆余弦関数(.NETではMath.Acos)を使いラジアン値に変換する。 こうして求まった角度がベクトルの傾きとなる。
まず始点(0,0)から指定されたプロット間隔rを半径とした円と、求まった傾きを持つ直線を仮想的に考え、その交点Pを求める方法を考える。
まず点Pから垂線と水平線を考え、それぞれのX軸とY軸との交点について考える。
従前に求めた角度と三角関数(.NETではMath.CosとMath.Sin)を用いることで座標の比率が求められる。
求めた比率に指定間隔を乗じるとオフセット値となる。
2つのフラグを判定しオフセット値を加算(減算)していく。
|
||
課題演算処理で求めた角度(=ベクトルの傾き)については演算誤差が発生するため、長い描画オブジェクト(km単位)だと終点での誤差が目立ちます。これを修正するためには、ベクトルを内分して指定間隔で傾きを求め直す補正を行うことで誤差を縮小できると思います。 |
||
参考コード(C#)
|