DOBON.NET DOBON.NETプログラミング掲示板過去ログ

球を描画するメソッド

環境/言語:[環境/言語:[Windows 7/VB.NET 2010] ]
分類:[.NET]

アンケート結果をビジュアル的に見せようと思っています。

画面を中央で左右に2分割し、「はい」の人数を画面左に赤の球で表示し、
「いいえ」は右に青の球を表示しようと考えました。


   はい   |  いいえ
−−−−−−−−+−−−−−−−−
○○○○○○○○|●●●●●●●●
○○○○○○○○|●●●●●●●●
○○○○○○  |●●●

上記の様なイメージです。

ところが、球を描画するメソッドが見つけられないため、
無理矢理以下の様なコードで球っぽいものを書いてみたのですが、
これを人数分書くのは大変です。

私の探し方がへたくそなだけで、.NETを熟知している方なら
「ぷぷ、1行で書けるのに…」ってな質問なのかも知れませんが、
球を描画するメソッドって無いのですかねぇ〜

----- 以下こんなの書いてみました ----------------------------

Imports System.Drawing.Text
Imports System.Windows.Forms.TextRenderer
Imports System.Drawing.Drawing2D

Public Class Form1

Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Dim canvas As New Bitmap(PictureBox1.Width, PictureBox1.Height)
Dim g As Graphics = Graphics.FromImage(canvas)
Dim gp As GraphicsPath
Dim gb As PathGradientBrush


g.CompositingMode = CompositingMode.SourceCopy
g.Clear(Color.Black)

g.FillEllipse(Brushes.Red, 10, 10, 100, 100)


gp = New GraphicsPath
gp.AddEllipse(14, 14, 90, 80)
'PathGradientBrushオブジェクトの作成
gb = New PathGradientBrush(gp)
'パスグラデーションの中心の色を白にする
gb.CenterPoint = New Point(40, 40)
gb.CenterColor = Color.White
'パス内の点に対応している色を指定する
gb.SurroundColors = New Color() {Color.Red}
g.FillEllipse(gb, 14, 14, 90, 80)


gp = New GraphicsPath
gp.AddEllipse(40, 94, 40, 16)
'PathGradientBrushオブジェクトの作成
gb = New PathGradientBrush(gp)
'パスグラデーションの中心の色を白にする
gb.CenterPoint = New Point(60, 102)
gb.CenterColor = Color.Salmon
'パス内の点に対応している色を指定する
gb.SurroundColors = New Color() {Color.Red}
g.FillEllipse(gb, New Rectangle(40, 94, 40, 16))


'リソースを解放する
gb.Dispose()
g.Dispose()

'PictureBox1に表示する
PictureBox1.Image = canvas

End Sub
End Class
上記の
g.CompositingMode = CompositingMode.SourceCopy

g.SmoothingMode = SmoothingMode.HighQuality
g.CompositingMode = CompositingMode.SourceOver
と変更してみました。
■No31815に返信(ぴちさんの記事)
1つ球を各処理を

Private Sub DrawBall(grp as Graphics, BallColor as Color, x as Single, y as Single)
    〜 ここにx,yを起点として球を各処理を記述 〜
End Sub

こんな感じにメソッドを用意しておけば
後はループでx,y,色を変えながらDrawBallを呼べばよいかと思います。
2013/10/02(Wed) 13:39:18 編集(投稿者)

やっぱり球を描画するメソッドというものは無いのですね?

ということで、ご指摘の通り自前でメソッドを作成してみましたが…
自分自身のセンスがイマイチ信用できないので、こんなんでちゃんと
球に見えているか不安です。

EXCELのオートシェイプでは簡単に描画出来るので、プロパティ等を駆使すれば
もっと素晴らしい球が描画出来るのでは?と色々いじってみましたが、私には
これが限界でした。


誰か「過去に俺の描いた球の方がカッコイイぜ!」という方、いらっしゃいませんか?


----- 以下こんな風に変えてみました ----------------------------
Imports System.Drawing.Text
Imports System.Windows.Forms.TextRenderer
Imports System.Drawing.Drawing2D

Public Class Form1

Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Dim canvas As New Bitmap(PictureBox1.Width, PictureBox1.Height)
Dim g As Graphics = Graphics.FromImage(canvas)

g.SmoothingMode = SmoothingMode.HighQuality
g.CompositingMode = CompositingMode.SourceOver
g.Clear(Color.Black)


Call subDrawSphere(g, Color.Red, Color.Coral, 10, 10, 100)

Call subDrawSphere(g, Color.Blue, Color.RoyalBlue, New Point(200, 10), 100)

g.Dispose()

'PictureBox1に表示する
PictureBox1.Image = canvas

End Sub

Private Sub subDrawSphere(ByVal p_grp As Graphics, ByVal p_SphereColor As Color, ByVal p_HighlightColor As Color, ByVal p_X As Integer, ByVal p_Y As Integer, ByVal p_Diameter As Integer)
Call subDrawSphere(p_grp, p_SphereColor, p_HighlightColor, New Point(p_X, p_Y), p_Diameter)
End Sub

Private Sub subDrawSphere(ByVal p_grp As Graphics, ByVal p_SphereColor As Color, ByVal p_HighlightColor As Color, ByVal p_Point As Point, ByVal p_Diameter As Integer)
Dim gp As GraphicsPath
Dim gb As PathGradientBrush
Dim _i As Integer
Dim _w As Integer
Dim _h As Integer
Dim _x As Integer
Dim _y As Integer
Dim _p As Point
Dim _c As Color

'ベースとなる円
p_grp.FillEllipse(New SolidBrush(p_SphereColor), p_Point.X, p_Point.Y, p_Diameter, p_Diameter)

For _i = 1 To 2
Select Case _i
Case 1
'球っぽく
_w = CInt(p_Diameter * 0.8)
_h = _w
_x = p_Point.X + CInt(p_Diameter * 0.04)
_y = p_Point.Y + CInt(p_Diameter * 0.04)
_p = New Point(p_Point.X + CInt(p_Diameter * 0.3), p_Point.Y + CInt(p_Diameter * 0.3))
_c = Color.White
Case Else
'ハイライト
_w = CInt(p_Diameter * 0.4)
_h = CInt(p_Diameter * 0.16)
_x = p_Point.X + CInt(p_Diameter * 0.3)
_y = p_Point.Y + p_Diameter - _h
_p = New Point(_x + _w \ 2, _y + _h \ 2)
_c = p_HighlightColor
End Select

gp = New GraphicsPath
gp.AddEllipse(_x, _y, _w, _h)
'PathGradientBrushオブジェクトの作成
gb = New PathGradientBrush(gp)
'パスグラデーションの中心位置を設定する
gb.CenterPoint = _p
'パスグラデーションの中心の色を設定する
gb.CenterColor = _c
'パス内の点に対応している色を指定する
gb.SurroundColors = New Color() {p_SphereColor}
p_grp.FillEllipse(gb, _x, _y, _w, _h)

'リソースを解放する
gb.Dispose()
Next

End Sub
End Class


ちなみに、私の目指す球はこんなかんじです。
添付ファイル: 1380688101.png (27 KB)
2013/10/10(Thu) 12:30:33 編集(投稿者)

質問タイトルにそぐわないとは思いますが。
目的は球を書くことでしょうか?アンケート結果の表示でしょうか?
求めるものは後者かと思うのですが。
球ビットマップを動的に張り付ければいいかとおもいます。背景を透過にしたければマスクすればいいですし。

あくまで綺麗な球を描きたいのであればDirectXあたりではないでしょうか。
■No31869に返信(るるさんの記事)
> 2013/10/10(Thu) 12:30:33 編集(投稿者)

目的はアンケート結果が一目で判るように表示することで、
球を描くのはその手段です。

“綺麗な”という部分は外連味以外の何物でも無く、無くても
良い部分なのですが、簡単に出来るのであれば折角なので綺麗に
見せたいなぁ〜と。

この掲示板に画像を貼り付けている通り、EXCELのオートシェープ
では簡単に描画できるので、その画像を保存しフォーム上に表示
するということも考えたのですが、フォームを全画面表示するので、
実行環境のディスプレーの大きさやスクエアかワイドか等で、球の
大きさが異なり、画像をストレッチすると微妙な出力結果になる
のかな?(ゴメンナサイここは未確認で語っています)と思いまして。
で、世に大勢いる私よりVBに詳しい人の中で、過去に球を描いたことが
ある人が居るのであれば知恵を借りたいと考えた次第です。

「EXCELでは簡単に出来るのに」という思いが根底にはあり、EXCELで
出来るなら.NETでもと…

DirectXですか…、食わず嫌いはイケナイのでしょうけど、まだまだ
私の手には持て余す気がして…
まぁ、覚えようとする努力を放棄しておいて、綺麗な描画がしたい
だなんて虫が良過ぎですね。
製造物に製造者の自己主張を含めること自体は大いに結構です。
しかし、そのために利用者側のリソースを多く使うと利用者に嫌われます。

別途描画しておいた画像を何種類か用意しておいて、条件によって切り替える程度に抑えるのが無難かと思います。
2013/10/11(Fri) 13:37:41 編集(投稿者)

DirectXを例には出しましたが・・・。
「アンケート結果をヴィジュアル的に見せる」という成果を得るためにDirectXにまで手を出すのは、あまり得策ではないと思いますので。趣味でやっているならいいのですが、仕事としてやっているのなら、それが評価されることはありません。DirectXを勉強しながら8時間ほどで作ったのと、ビットマップ貼り付けで1時間ほどで作ったのなら、コスト的にどっちがいいかは言うまでもないですし、見た目が同じだとすれば、アンケート(もしくはアンケートを作るこのアプリ)を受け取る側にとっては内部でどのように実装しているかはまったく関係ない世界ですから。それよりも、アンケート結果を別表現で見せることに注力したほうがいいかと思います。たとえば円グラフなら全体におけるパーセンテージが一目瞭然ですし。その他の質問結果との相関、比較とか。アンケートを見る人が有益な情報を得られるようにいろいろな表現パターンで表示すれば、価値の高いソリューションになるのではないでしょうか。
もちろん、いろんなことに試行錯誤し、また新しい技術に手を出すことは自身のスキルを上げる上で重要なことだと思ってますよ。
えらそうなことを書きましたが、私もよく迷走してます^^;。
変な方向に話がいっちゃいました。すいません。
2013/10/31(Thu) 11:30:59 編集(投稿者)

前提として、趣味グラマが趣味グラムを作成していると考えてください。

上記に記載した程度のメソッドで描画を行う方が、画像のリソースを数種類
埋め込むより、微々たるものかもしれませんがexeの容量、配布時の通信量、
起動時間、など利用者側のリソース消費は抑えられるかな?と考えました。


また今回、球を描画するsubDrawSphereというメソッドを作成したことにより
今後、別の趣味グラム、…たとえば灰色と赤の球を描画しメニューカーソルの
替わりにするとか、色々応用できるかな?と。

○鈴木一郎
●坂上二郎
○北島三郎
○伊東四郎

そういった点で言えば、目的は「アンケート結果の表示」でかつ「球を書く」
となるでしょうか?


“綺麗な”の部分にこだわり、即答できる方の目に留まれば…と放置して居り
ましたが、これ以上は解答が付かなそうなのでここで締めさせていただきます。
結論といたしましては「上記のメソッドのまま行く」としました。
メソッド名がハンガリアン記法になっている件は目をつぶってください。


趣味グラマとしてはプログラムに対する他人の意見を聞けて大変楽しかったです。
何かあったら、また来ると思いますのでよろしくお願いします。


_/_/_/ 追記 _/_/_/_/_/_/_/

あわ、「解決済み!」にするの忘れた。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板