ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

Visual Studioコミュのベジェ曲線を扱うには?

  • mixiチェック
  • このエントリーをはてなブックマークに追加
AdobeのIllustratorやFlashのようなベクタ図形を描くにはどうすればいいのでしょうか?
ベクタ図形はベジェ曲線を使えばいいのでしょうか?

MFCでベジェ曲線を扱うには「CDC::PolyBezier」「CDC::PolyBezierTo」「CDC::PolyDraw」の3つがあるようですが、色やテクスチャで塗りつぶしができないようです。

Visual Studio 2005 Professional
Windows Vista Ultimate

コメント(23)

色やテクスチャで塗りつぶしをしたいならDirectXやOpenGLで実装されるのがいいのではないでしょうか

DirectX10.0でジオメトリシェーダやストリームアウトプットなど用いると高速に処理できるかもしれません。
つよしさん

DirectXやOpenGLでどうやったら実装できるでしょうか?

両方とも少しかじっていますが、ポリゴンやラインは全て直線で構成されているので、曲線は無理な気がします。
たけしさん

制御点を直接描画するのではなく、制御点を元にテッセレートしてポリゴンを
生成する必要があります。

この曲面計算→テッセレート流れはプリミティブ描画前にソフトウェアでやる方法と制御点のみを渡し、ジオメトリシェーダー内で曲面計算とテッセレートを行う方法があります。

おそらく後者の方が高速に動作しますが、2Dの場合、ソフトウェアでやってもさほど問題にならないと思います。

私が以前、前者の方法でやった時は3000ポリゴンの制御点を元に12000ポリゴンの曲面を作成する程度なら問題なく動作させる事が出来ました。

リアルタイムに曲面を生成する必要が無いのであれば、事前計算させる事で速度を改善させる事が出来ると思います。


シンターナさん

WPFがありましたね。
一時期使っていたのに、今ではすっかり忘れていました。

つよしさん

そのプログラムを見せていただけないでしょうか?ソースまでは無理でも、どう動いてるかみたいです。
たけしさん

残念ながら、仕事でやった事なのでお見せする事ができません。

ジオメトリ関連のソースコードはネット上にたくさん落ちているのでそちらを参考にするといいかもしれません。例えばBlenderのソースなどどうでしょうか?
つよしさん

残念。

Blenderのソースですが、ビルドの仕方さえ分からずに諦めました。

やっぱりWPFが一番簡単そうです。
APIから察するにCloseFigureでパスを閉じてから
FillPathをすると塗りつぶしできたと思います。
MFCだと両方ともCDCですね。

.NETなら
System.Drawing.Drawing2D.GraphicsPathを使って
System.Drawing.Drawing2D.GraphicsPath.AddBezier
などで個々の要素を描画してから
System.Drawing.Drawing2D.GraphicsPath.CloseFigure
それから
System.Drawing.Graphics.DrawPath
System.Drawing.Graphics.FillPath
郁恵さん、ありがとうございます。

以下のようにしてベジェ曲線を塗りつぶせました。

POINT PT [7] = { 200,50, 20,10, 40,10, 60,50, 80,190, 100,190, 120,50 }; // 点の配列を用意
pDC->BeginPath();
pDC->PolyBezier( PT, 7 ); // 7個の点を使って連続した2本のベジェ曲線を描画
pDC->EndPath();
CBrush* pbr = (CBrush*)pDC->SelectStockObject(BLACK_BRUSH);
pDC->FillPath();
pDC->SelectObject(pbr);

CloseFigureしなくても勝手にパスを閉じてくれるようです。
□ 質問「Path上の点と点の間の曲線上の点」 □

GDIではベジェ曲線に限界を感じたので、GDI+でベジェ曲線を描くことにしました。

そこでベジェ曲線を構成する点と点の間の曲線上をクリックした際に、点と点の間にもう1点追加するにはどうすればいいでしょうか?
どうやってクリックした座標が曲線上か判定できるでしょうか?

Visual Studio 2005 Professional SP1
Windows Vista Ultimate
たけしさん

ベジェ曲線を示すポイントはMicrosoft版のベジェ曲線だと
4点でワンセット(終点と始点は連続するベジェ曲線の始点、終点と共有可)なので
たけしさんのイメージしたものとは勝手が違います。
ためしにベジェ曲線を描く時に指定したポイントを±1ピクセル位で
Rectangleを使って描画してみてください。

それと、点の追加は間に挟みこむ基点と基点の前後に途中の点が2個ずつ入るように調整が必要です。
ドローソフトでも結構やっていることですが、描画に必要なポイントを点で示して、
その位置をマウスで移動させてもらうほうが現実的かと。
郁恵さん、ありがとうございます。

頂点とコントロール点は描画してみました。
Microsoft以外でベジェ曲線に強いライブラリなどあるのでしょうか?

>ドローソフトでも結構やっていることですが、描画に必要なポイントを点で示して、
>その位置をマウスで移動させてもらうほうが現実的かと。

どういうことでしょうか?
2頂点を選択して「2点間に頂点を追加」みたいなコマンドを作るのではないですか?
たけしさん
「維持したまま途中に基点を追加」については、
計算式がある(検索すればすぐ見つかる)のでプログラム的にはがんばり次第で
クリックした位置を再計算できるとは思います。
でも私には難しい(と言うかやった事がない)です。

もう一つは、「どこに点を挿入するか」ですが、
ポイント(基点)をクリックして、その前か後に新しい基点(+方向点)を
挿入する仕様にすれば良いと思います。

描画の利用に関して言いますと、PolyDrawを使えば曲線と直線を取り混ぜて使えるので
ベジェ曲線をPolyDrawで実装する方がお勧めです。PolyDraw最強。
プログラマにはパスまでたどり着くまで遠いのですが、
デザイナーも「パス」が通じます。やはり高等技術には違いないですけど。
郁恵さん、ありがとうございます。

やっぱり難しいですか。

3Dの場合ポリゴンは直線のみですが、2DのPolyDrawは曲線もできるのですね。
□ 質問「塗りつぶしについて」 □

画像のように塗りつぶしをしたいのですが、同一のパス上で複数の塗りつぶし色と塗りつぶしなしをするにはどうすればいいのでしょうか?

こういう場合、パスを上下2つに分けて、上下2つのパスが重なる部分は、上下それぞれパスを描くのでしょうか?
そうするとパス同士の接触判定が必要になるのでしょうか?
たけしさん
複数のパスならできますが・・・・
一つのパスなら理論上塗りつぶし規則の都合で無理ではないかと。
二つのパスなら出来ると思います。

念のために、BeginPathで円を2個書いてEndPathで一連の動作をまとめると、
EndPathの復帰値でhPathが取れるので、hPathを引数にしてGetPathしてみては
どうでしょう。(ごめんなさい、Win32APIレベルで書いています)
なお、GetPathの第2〜4引数はPolyDrawのデータ構成と共通です。

それと、2DもポリゴンはPolygonです。
郁恵さん、ありがとうございます。

GDI+に移行したためBeginPathとかはできません。
やっぱりWin32APIのほうが有利でしょうか?
GDI+と言うと、GraphicPathクラスかPathDataクラスでしょうか?
AddBezierなどで線を描画してGetPathDataを実行するとPathDataクラスが
取得できるので、その中身を見てください。
Countがポイントの数でPointsが各ポイントの座標。Typesが個々のポイントが直線か、曲線かを示す値です。
19の図形を実現するにはリージョンを使う事になるかもしれません。
郁恵さん、ありがとうございます。

GDI+でもできそうですね。

ログインすると、残り5件のコメントが見れるよ

mixiユーザー
ログインしてコメントしよう!

Visual Studio 更新情報

Visual Studioのメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。

人気コミュニティランキング