• ベストアンサー

円弧の描画方法

ametsuchiの回答

  • ベストアンサー
  • ametsuchi
  • ベストアンサー率31% (81/257)
回答No.3

問題を2つに分けましょう。 (1) 3点から円弧を求める方法: とりあえず約束として、 P0:円弧始点 P1:円弧通過点 P2:円弧終点 O:求める円弧中心 R:円弧半径 とします。時計回りか、反時計回りかはここでは問いません。 線分P0P1、線分P1P2 にOから下ろした垂線の足は線分の中点ですから、線分長を L01 = dist(P0, P1) L12 = dist(P1, P2) として、 <P1-P0, O> - 0.5*L01^2 = 0 <P2-P1, O> - 0.5*L12^2 = 0 です。ここに、<, >は内積を表わします。 これは、Oの成分、Ox,Oyに関する連立一次方程式になり、 det = (P1x-P0x)*(P2y-P1y) – (P1y-P0y)*(P2x-P1x) として、 Ox = 0.5* {L01^2*(P2y-P1y) – L12^2*(P1y-P0y)} / det Oy = 0.5* {-L01^2*(P2x-P1x) + L12^2*(P1x-P0x)} / det……………Equ.1) が求まります。但し、3点の内2点が重なるとか、3点が一直線上に並ぶ場合はdet=0になるので注意が必要です。「円弧は求まらない」としてエラー処理しなくてはなりません。 半径は以下のように容易に求まります。 R = |P0 - O|…………………………………………………………………Equ.2) 始終角を求めます。先ず、 θ0 = atan2(P0y-Oy, P0x-Ox) θ1 = atan2(P1y-Oy, P1x-Ox) θ2 = atan2(P2y-Oy, P2x-Ox)…………………………………………………….Equ.3) として、円弧中心から見た3点の角度が-π~+πの範囲で求まります。 これを θ0’ = 0 θ1’ =θ1 -θ0 θ2’ =θ2 -θ0………………………………………………………………………Equ.4) と始点基準にします。 これを、0~2πの値に変換して、 ・θ2’ < θ1’ なら反時計回り ・θ1’ < θ2’ なら時計回り なのです。あと処理の都合のため、時計回り回りなら始終点を入れ替わると、必ず反時計回りになります。以下、「円弧」と言うと、 ・中心(上のOですが、あなたのプログラムでは、「x0, y0」です) ・半径(上のRですが、あなたのプログラムでは「r」です) ・始角(反時計回り) ・終角(反時計回り) で表現されるものとします。ただ、Equ.3)で分かるとおり、既に、コストのかかる逆三角関数を3回も用いています。 (2) 円弧ベクター->ラスター変換: 先ず、「ミッチェナーのアルゴリズム」ですが、ご存知のように、 1) 円を8分割し、対称性を利用して基本1パタン(東->北、0°~45°)を利用。 2) 基本パタンでは、y:必ず1Pixelずつ増加、x:0または1Pixel減少。 3) x: 0または-1を判断するのに、「真円からのx方向差分」を巧妙な計算で求める。 ただし、この差分は、x: 0または-1で異なる。 という非常に巧妙な仕掛けになっている訳です。三角関数は勿論、sqrt()も一度も使われていません。しかも近似計算ではなく、誤差は1/2Pixel以内というか、可能な限りでの正確な計算になっています。 本題に入ると、whileループに入る前に、(1)で求めた始終角から、 0) この1/8セルの処理区分, 開始y, 終了y 1) この1/8セルの処理区分, 開始y, 終了y 時計回り 2) この1/8セルの処理区分, 開始y, 終了y 時計回り 3) この1/8セルの処理区分, 開始y, 終了y 4) この1/8セルの処理区分, 開始x, 終了x 時計回り 5) この1/8セルの処理区分, 開始x, 終了x 6) この1/8セルの処理区分, 開始x, 終了x 7) この1/8セルの処理区分, 開始x, 終了x 時計回り なる8つの行からなるテーブルを作ったら如何でしょうか?8個固定ですから配列でなくてもいいです。 ・ 1/8セルの処理区分: (1) 全域無効、描かない、 (2) 全域有効、描く。 (3) 一部有効、開始~終了範囲だけ描く。 ・開始・終了y(x):必ず開始<終了になります。 0)~7)何れも、最大で=r、最小で=0.707*rです。ここは気を付けて下さい。 No.2で「forループにして、forループインデックスの範囲」てなこと言いましたが、whieループでいいと思います。「開始終了y(x)」を角度から求めるには始終点位置の角度に関しては残念ながら、三角関数を一度ずつ使わなくてはいけないでしょう。それ以外の場合は、r0.707*rです。三角関数計算は不要です。

関連するQ&A

  • Bresenhamのアルゴリズムを用いた円弧描画

    Bresenhamを用いた直線、円、円弧(45度単位)での変換 アルゴリズムは調べることが出来たのですが、円弧の任意の角度 の変換方法が分かりません。 参考資料などありましたら 教えていただけないでしょうか? 例えば、  始点、終点、回転の向きを指定するとか、  30度と角度を指定する等。 宜しくお願い致します。

  • 円弧の描画について

    円弧の描画について お世話になります。 Visio2007を使用しています。 Visioで円を描画し、その円の情報を基に計算を行い、円弧の作成をしたいと考え ていますが、計算方法が分からずご質問させて頂きました。 以下の【元となる情報】から【求める情報】を計算にて求めます。 【元となる情報】 左上X座標:円の左上X座標 左上Y座標:円の左上Y座標 幅:円の幅 高さ:円の高さ 始点角度:円弧の始点の角度(円の中心から右方向を0度とし       時計回りの角度) 終点角度:円弧の終点の角度(始点角度を0度とし時計回りの角度) (始点角度と終点角度は1度単位で設定をします) 【求める情報】 http://msdn.microsoft.com/ja-jp/library/cc344284.aspx 例えば、 ・始点角度が0度、終点角度が90度の時は円の右下1/4の円弧が作成される ・始点角度が90度、終点角度が180度の時は円の左半分の円弧が作成される 以上の様な円弧を求めるような計算方法をご存知でしたらご教授 お願い致します。

  • 傾いた楕円の描画方法

    PCでの楕円の描画は、ライブラリに組み込まれていますが、水平(または垂直)の楕円については、関数1行で描画することができます。 ところが、傾いている楕円については、描画することができません。 そこで、ミッチェナーのアルゴリズムで円を描くプログラムを変形して、上下(左右)のプロット位置をずらせば、一応、楕円は描画できるので、さらにプロットする部分に回転をかければ回転した楕円を描画できると考えて、プログラムを作成してみました。 しかし、あまり綺麗な楕円を描画できません。 ミッチェナーのアルゴリズムを上下に圧縮した時点で、左右の部分が少し密になり(これは許容できる範囲ですが)それを回転させるとき、実数計算になるため、最終的な位置は、ドットのどちらかになってしまうので、あまりうまくいきません。 ミッチェナーのあるごりずむの原理を使って、傾いた楕円の式から、直接プロットしなければ綺麗な楕円を描画することができないと考えます。 最終的に欲しい関数は、傾いた楕円の外接する4点の座標を与えて、描画する関数です。

  • AutoCADで円弧を描く方法について

    AutoCAD Mechanical 2009を使用しています。 下記の円弧(又は円)を描きたいと考えております。 ・半径7000 ・長方形の1辺Aに接し、Aの中点に接する ・長方形の2辺B,Cを通る(通過点は指定無し) 無理やり描くには、辺Aの中点から長さ7000の線分を引き、その線分の端点を中心とする半径7000の円を描けばよいのですが、 極力無駄な線は描かずに、効率よく描く方法をご教授願います。 宜しくお願い致します。

  • 円弧の描画について

    ある参考書の内容について分からない点があります。(VB6です。) '変数と定数の定義 Dim startAngle As Double Dim endAngle As Double Const pi = 3.14152965 '角度の初期値 startAngle = 90 endAngle = 315 '線の色の指定 ForeColor = QBColor(4) '円弧の描画 circle (2000,1500) , 1000, , startAngle * pi / 180, endAngle * pi/180 End Sub 変数の定義で、startAngleとendAngleがDouble型で宣言されているのに、初期値は小数ではなく整数なのはなぜでしょうか。たぶん、初期値は整数だけど、startAngle * pi / 180, endAngle * pi / 180が小数になるからDouble型にしていると思うのですが、このあたりのことを教えていただけますか。

  • AutoCAD LT 2007での長方形描画について

    AutoCAD LT 2007です。 4点ABCDからなる長方形の対角2点の座標(”点Aと点C”または ”点Bと点D”)と長さを指定すれば、指定した長さ分内側に 長方形が描画出来るようなコマンド?マクロ?を作成することは 出来ますでしょうか? 例えば、座標0,0&座標7,10、長さ2(元の長方形)とすれば、 座標2,2&座標5,8を対角とする長方形(新たに描画される長方形)が 描けるといったようなことです。 教えて下さい。 何卒よろしくお願い申し上げます。

  • 【Fash actionscript】楕円を描画したい

    actionscriptで楕円を描画したいです。 円を描画するとこまでは、以下ページに説明があったので、 http://www.geocities.jp/swf_daisuke/school/class3.html できたのですが、応用ができなくて困ってます。 楕円といっても色々あるでしょうが、長方形が内接するような楕円です。 ご指導のほど、よろしくお願いいたします。

    • ベストアンサー
    • Flash
  • 線分や円弧をクリックして選択するプログラム

    CAD等で描かれた2次元の図面上の任意の線(線分や円弧)をクリックして選択するプログラムを作っています。 いまは叩き台として、各線のバウンディングボックス(線分や円弧を囲む最小の長方形)の情報(対角線の両端座標) が入った配列(実際はC++のSTL vectorです)を用意して、クリックした座標の一番近くに在る、若しくは内包する バウンディングボックスを線形探索して、見つかったバウンディングボックスに所属する線がクリック許容範囲内 であるかを分析しています。 しかし、この方法では線の数が少ないうちは良いのですが、大規模な図面になると時間が掛かってしまい 使い物になりません。 このような場合、どういったデータ構造でどのようなアルゴリズムで探索するのが良いのでしょうか? なにか定石的なものがあるのでしょうか? 恥ずかしながら、探索アルゴリズムというと学生の時に2分探索法等を習った程度で、2次元以上の高次元のもの 扱うアルゴリズムはピンときませんでした。

  • パラメトリック曲線の描画アルゴリズムについて

    x = f(t) y = g(t) のように表せるパラメトリック曲線を2次元のビットマップ画像に描画したいと考えています。 (たとえばNURBS) 描画アルゴリズムですが、tを適当に変化させてx,yの組を得てその点を打つことにより曲線 を書くことはできます。 ただこの場合tの増分の選び方が大きいと穴が開いてしまいますし、小さいと何度も同じx,yを 描画することになってしまい効率が悪いです。 x、yの適切な変化量(たとえばプラスマイナス1)となるtの増分を求められればいいのですが、 具体的なアルゴリズムが思い当たりません。 他の方法でも構いませんが、一般的にパラメトリック曲線を描画する高速なアルゴリズムをご存知 でしたらご教授いただけたらと思います。

  • 円の描画の太さを指定できるCコード

    円の描画を行うCコードを記述していますが Michenerのアルゴリズムにより円を下記サイトを参考に記述できました。 しかし、アルゴリズムの理解不足の為、円の太さを指定できるようにしたいのですが、なかなか上手くいっておりません。 もし、円の太さを指定できるCコードなどありましたら教えていただけないでしょうか?