前提
ベジエ曲線を、美的曲線へ変換する手前で躓いてます。
該当のソースコード
def bezier_curve_derivative(Q, t): """ 制御点 Q とパラメーター t によって定義されるベジェ曲線の一次導関数を計算します。 """ n = len(Q) - 1 db_dt = np.zeros((len(t), len(Q[0]))) for i in range(n): db_dt += n * binom(n - 1, i) * (1 - t) ** ( n - 1 - i) * t ** i * np.subtract(Q[i + 1], Q[i]) return db_dt def binom(n, k): """ 二項係数を計算します (n は k を選択します)。 """ return math.comb(n, k) def bezier_to_Biteki(Q): """ 制御点Qで定義されるベジェ曲線を美しい曲線に変換します。 """ t = np.linspace(0, 1, 100) px, py = bezier_curve(Q) # Calculate rho and ds/drho dx_dt, dy_dt = bezier_curve_derivative(Q, t) rho = np.sqrt(px ** 2 + py ** 2) ds_drho = np.sqrt(dx_dt ** 2 + dy_dt ** 2) / rho # Calculate a and c a, c = miura_curvature(rho, ds_drho) # Calculate beautiful curve beautiful_rho = np.exp((a * np.log(rho)) + c) beautiful_x = px * beautiful_rho / rho beautiful_y = py * beautiful_rho / rho return np.array([beautiful_x, beautiful_y]).T
発生している問題・エラーメッセージ
エラーメッセージ Traceback (most recent call last): File "C:/Users/phanton/PycharmProjects/pythonProject1/kyokusen/t2.py", line 23, in <module> beautiful_x, beautiful_y = bz.bezier_to_Biteki(Q) File "C:\Users\phanton\PycharmProjects\pythonProject1\kyokusen\t2_1.py", line 70, in bezier_to_Biteki dx_dt, dy_dt = bezier_curve_derivative(Q, t) File "C:\Users\phanton\PycharmProjects\pythonProject1\kyokusen\t2_1.py", line 41, in bezier_curve_derivative db_dt += n * binom(n - 1, i) * (1 - t) ** ( ValueError: operands could not be broadcast together with shapes (100,) (2,)
試したこと
チャットGPTにエラーについて聞き、二つの配列の形状が合わないことは理解し、修正点も聞いてみたのですが、何も修正されていないコードが返されてしまいました。
また、以下URLより、調べてもみたのですがネットからも調べてみたのですが、どう変えていいかわからづじまい。
https://www.delftstack.com/ja/howto/python/python-operands-could-not-be-broadcast-together-with-shapes/
上記のエラーについて助言いただけると幸いです。
補足情報(FW/ツールのバージョンなど)
python 3.8
> bezier_curve_derivative(Q, t)
上記の引数 Q, t はどのような型(配列の場合は次元)を想定されていますか?
質問ありがとうございます。
二次元の配列で返したいと思っています
> 二次元の配列で返したいと思っています
戻り値の話ではなく引数について質問しています。
すみません、Qは二次元で、tは一次元です。
> Qは二次元で、tは一次元です。
両方ともnumpy.ndarrayですか?
>両方ともnumpy.ndarrayですか?
Qはnumpy.ndarray、tはnumpy.linspaceです。
> Qはnumpy.ndarray、tはnumpy.linspaceです。
え?「tはnumpy.linspace」は本当ですか?これのことですか?https://numpy.org/doc/stable/reference/generated/numpy.linspace.html
numpy.ndarrayではなくて関数ですか?そうなると len(t) のところでエラーになるはずなのでちょっと分からないです。
ソースコード上では t = np.linspace(0, 1, 100) となっているので t は numpy.ndarray でしょう。
あと、binomとは何でしょうか?
binom() を取り除いて実行してみると同じエラーが発生します。
db_dt += n * (1-t)**(n-1-i) * t**i * np.subtract(Q[i+1], Q[i])
~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
ValueError: operands could not be broadcast together with shapes (100,) (2,)
n * (1-t)**(n-1-i) * t**i の shape は、t の shape が (100,) で n と i はスカラーなので (100,) になります。また、Q の shape が (2, n+1)なので、np.subtract(Q[i+1], Q[i]) の shape は (2,) になります。したがって、
n * binom(n - 1, i) * (1 - t) ** (n - 1 - i) * t ** i * np.subtract(Q[i + 1], Q[i])
の式には何らかの誤りがある、ということになるのでしょう。
>あと、binomとは何でしょうか?
二項係数計算に使う関数です。入れるのを忘れていました。修正します。
> db_dt += n * binom(n - 1, i) * (1 - t) ** (
n - 1 - i) * t ** i * np.subtract(Q[i + 1], Q[i])
上記の各変数の形状(行列?スカラー? 行列の場合の行列数)を確認して、どの計算に問題があるのか確認するのが良いかと思います。

回答1件
あなたの回答
tips
プレビュー