🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Qt

QtはGUIプログラムの開発で広く使われているクロスプラットフォーム開発のフレームワークです。

Q&A

解決済

1回答

1076閲覧

PyQt5で正確な円を描画したい

doomori

総合スコア24

Qt

QtはGUIプログラムの開発で広く使われているクロスプラットフォーム開発のフレームワークです。

0グッド

0クリップ

投稿2020/01/04 02:46

前提・実現したいこと

趣味でPyQt5にてCADを作成しています。
各Line,Ellipse,ArcはQGraphicsPathItemを
拡張して作成しました。

発生している問題・エラーメッセージ

Line,Ellipse,ArcなどをTrimする機能を実装していた際に、
拡大していくとつながっていないことに気づきました。
(延長がたりなかったり,オーバーしていたり)
寸法的には0.03以下のレベルですが、CADでは致命的です。
Line同士のTrimではそういうことは起きておらず
いくら拡大してもきちんと繋がっています。

試しに、QGraphicsPathItemでEllipseを描画し、
1度づつ計算させたpointを重ねてみると
イメージ説明
イメージ説明
のように0.02ほどずれて描画されています。

該当のソースコード

Python

1ellipse = EllipseItem(3.0,50.0,70.0,70.0) 2# ellipse = QGraphicsEllipseItem(3.0-70.0,50.0-70.0,70.0*2,70.0*2) 3 4#Ellipse沿いに1°づつ点を置いています 5for i in range(360): 6 p = posEllipse(ellipse,i) 7 point = PointItem(p.x(),p.y()) 8 self.addItem(point) 9 10#円の中心からdeg度の位置を求めています 11def posEllipse(ellipse,deg): 12 theta =np.deg2rad(deg) 13 c1 = ellipse.center().x() 14 c2 = ellipse.center().y() 15 c = np.array([c1,c2]) 16 r = ellipse.radius() 17 unit = np.array([1,0]) 18 unit = unit.reshape(2,1) 19 p = c+r*np.dot(rotationMatrix(theta),unit).A1 20 return QPointF(p[0],p[1]) 21

試したこと

QGraphicsPathItemでなく
QGraphicsItemへの拡張に修正しても同様の現象が
起きてしまい、qt自体?の描画の問題なのでしょうか?
いくら拡大しても、すくなくとも0.0001レベルでは
円と点が一致している図を描きたいと考えています。

申し訳ありませんが、
よろしくお願いします。

補足情報(FW/ツールのバージョンなど)

Python3.6.5 64bit
PyQt5.14

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

PyQtは知りませんが状況からしてベジエ曲線のパスで円を近似しているようですね。
ベジエで正確な円は描けませんが見た目に円と区別の付かないものを描くのは容易なのでよく用いられます。

すくなくとも0.0001レベルでは

と完全に正確でなくてもよいようなので、パスの分割を細かくするのが楽でしょう。
Arcを細かく描けばそれでよさそうな気がしますが、原理的なことも言っておくと、
StackOverflowの「How to create circle with Bézier curves?」によれば最適なコントロールポイントの位置は以下だそうです。

for Bezier curve with n segments the optimal distance to the control points, in the sense that the middle of the curve lies on the circle itself, is (4/3)*tan(pi/(2n)).

投稿2020/01/04 04:48

ikadzuchi

総合スコア3047

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

doomori

2020/01/04 07:27

ありがとうございます。 addArcやaddEllipseなどの関数がすでにあるので、そのまま利用できると 考えていましたが、甘かったようです。これ以上の精度が必要な時は 自分で実装してくださいということですね、、ベジェ曲線について調べてみます。 ちなみにEllipseを分解すると12の要素で構成されていました、これをもっと 増やすように実装を勉強していきます。 ありがとうございました。
doomori

2020/01/06 06:26

Ellipseを分解すると12の要素で構成されていましたと書きましたが、 誤解を与える表現でした、正しくは円を4分割しベジエ曲線で描写されていました。 円を36等分し直してベジエ曲線で実装し直すことで、求めるものができました。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問