気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答3件
0
python3で,ある点郡をなぞるような2直線を引きたいと考えております.
イメージとしては下図のとおりです.ここでは赤線を推定したいです.
※あくまでこちらの創造出来る範囲で答えさせて頂きます。
点郡ということは散らばっているのをイメージしましたので、配列順で線を引いていくだけだと味気ないと思います。多分そういうことをしたいのではないと思います。
1回目は単純に点郡との距離が一番近いところに線を引っ張り、2回目以降は一つ前の線の進行方向と近しい点のベクトルの内積が最も0に近い方向に進んでいく。
この方法なら、しっかりと点郡に沿って線が引けるのではないかと思います。
投稿2020/03/10 06:30
総合スコア3307
0
ベストアンサー
とりあえずその線の式について考えます。パラメータ4つの式になるはずです。
plain
1y = ax + b (x < c) 2y = dx + (a - d)c + b (x >= c) 3# (c, ac + b)を通る傾きdの式なので 4# y - ac - b = d(x - c) (x >= c) 5# である。上式二行目はそれを整理したもの
素晴らしいことに、式がわかればscipy.optimize.curve_fit
を使って最小ニ乗推定を行うことができます。これだと多少ノイズがあったりしても上手く解けます。
scipy.optimize.curve_fit — SciPy v1.4.1 Reference Guide
(今回の関数はx=cの点で微分できないのだと思いますが、これで数理的に厳しいことになるのかどうかは正確には把握できていないので、識者の方のご意見を伺いたいです)
(ちなみに、ノイズがないなら、各隣接点同士を結ぶ傾きをすべて求めればいいです。出てくるユニークな値は2つになるのでそれが上の式のaとdで、あとは適当な点を使ってb, cのパラメータを求めれば良いです)
python
1import numpy as np 2import matplotlib.pyplot as plt 3from scipy.optimize import curve_fit 4 5a, b, c, d = -1, 2, -3, 4 6 7def func(x, a, b, c, d): 8 """ 9 y = ax + b (x < c) 10 y = dx + (a - d)c + b (x >= c) 11 # (c, ac + b)を通る傾きdの式なので 12 # y - ac - b = d(x - c) (x >= c) 13 # である。上式はそれを整理したもの 14 """ 15 16 mask = x < c 17 result = np.empty(dtype=np.float64, shape=x.shape) 18 result[mask] = a * x[mask] + b 19 result[~mask] = d * x[~mask] + (a - d) * c + b 20 return result 21 22x = np.arange(-10, 10, 0.5) 23y_ = func(x, a, b, c, d) 24y = y_ + np.random.normal(size=x.shape) 25result = curve_fit(func, x, y) 26plt.scatter(x, y, label="samples", alpha=0.5) 27plt.plot(x, y_, linestyle="--", label="true") 28plt.plot(x, func(x, *result[0]), linestyle="--", label="estimated") 29plt.title("a:{:.2f} b:{:.2f} c:{:.2f} d:{:.2f}".format(*result[0])) 30plt.legend() 31plt.savefig("result.png") 32
悪くない感じでフィッティングされます。
追記
でもこれだと、x方向に折り返すような関数は駄目なはずなので、もう少し改良の余地がある。できるようになる座標変換を考えることはできるはずなので、まあなんとかなるとは思うのですが。しばらく考えさせてください(先に思いついた方は回答を投稿していただけると嬉しいです)。
投稿2020/03/10 06:30
編集2020/03/10 07:02総合スコア30935
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
点の並び順が直線上になっているならば、2点間の線分(の傾き)を算出しながら進み、傾きが変化したところが曲がり角ですから、最初の点→曲がり角の点と、曲がり角の点→最後の点、の2直線を引けば済みますが……そういうことではないですよね?
必ずしも2直線上には並んでいない点群から、2直線でなぞりたい、のですよね?
であれば、点群からもっとも近似する「曲線」を作成し、その曲線の両端点での接線を出す……のかな?
投稿2020/03/10 01:21
総合スコア13703
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。