C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[8]: 異なるカラーを自動で割り振る方法


(過去ログ 174 を表示中)

[トピック内 13 記事 (1 - 13 表示)]  << 0 >>

■100137 / inTopicNo.1)  異なるカラーを自動で割り振る方法
  
□投稿者/ 寺 (1回)-(2022/07/06(Wed) 18:33:30)

分類:[.NET 全般] 


VB.NETを使って
自動でグラフを生成するプログラムを作っています。

Excelで散布図を作った場合、カラーが被らないように自動的に異なるカラーを割り振ってくれます。
この自動でカラーを割り振る機能を作りたいのですが、
10〜20個くらいまでなら手作業で登録できますが、
それ以上になってくると非常に面倒になります、

ランダム関数を使ったり、
For文で異なる配色をする方法も考えましたが、
赤→青→緑→・・・
のようにできる限り、見た目で判別しやすいカラーを順番に登録したいため、
良い方法が思い浮かびません。
(つまり、赤とか濃い赤、ベージュなど似たような色を連続して登録しないような仕組みが必要という意味です)

自動で配色してくれる機能って.NETに備わっているのでしょうか?

また、良いアルゴリズムがありましたら
教えてくださいませ。


引用返信 編集キー/
■100138 / inTopicNo.2)  Re[1]: 異なるカラーを自動で割り振る方法
□投稿者/ 伝説のカレー (26回)-(2022/07/06(Wed) 19:42:18)
> また、良いアルゴリズムがありましたら

思いつきで
人間の目は輝度に敏感なので輝度を計算して隣り合う色の輝度の差が大きくなるようにすればいんじゃないですかね

たとえば
1,2,3,4,5,6
という値があった場合
1,2,3
4,5,6
と半分に分けて
1,4,2,5,3,6
と並べれば隣り合う値の差が大きくかつ均一になるんじゃないかなって思いました
引用返信 編集キー/
■100139 / inTopicNo.3)  Re[2]: 異なるカラーを自動で割り振る方法
□投稿者/ 伝説のカレー (27回)-(2022/07/06(Wed) 19:52:18)
> つまり、赤とか濃い赤、ベージュなど似たような色を連続して登録しないような仕組みが必要という意味です

あ、色相を良い感じに変えたいってことですかね
HSL色空間で計算すれば色相だけ変えられます

プログラムで計算してもいいですけど
最近のブラウザはhslをcssで指定できるのでJavaScriptであらかじめ色のリストを作っておいて
プログラムではそれを順番に使うとかでも良いかもしれないです

引用返信 編集キー/
■100140 / inTopicNo.4)  Re[3]: 異なるカラーを自動で割り振る方法
□投稿者/ くま (215回)-(2022/07/06(Wed) 21:12:32)
2022/07/06(Wed) 21:22:52 編集(投稿者)

自分なら基本色はWebセーフカラーの216色を基本に
https://www.colordic.org/s
http://www.htmq.com/color/websafe216.shtml

近い色や使わない色(白黒)を除外したリストを作成
あとはランダムに抽出か、初めの登録時点で色差があるようなリストを登録しておいて対応かな?
計算で割り出すよりも一度Excel等で色見本リスト作って確認したほうが後々の事も考えると
楽ですよ。
引用返信 編集キー/
■100141 / inTopicNo.5)  Re[3]: 異なるカラーを自動で割り振る方法
□投稿者/ KOZ (261回)-(2022/07/07(Thu) 00:44:10)
2022/07/07(Thu) 09:15:03 編集(投稿者)
No100139 (伝説のカレー さん) に返信
> HSL色空間で計算すれば色相だけ変えられます

「HLS色空間」
https://ja.wikipedia.org/wiki/HLS%E8%89%B2%E7%A9%BA%E9%96%93

から計算式を拝借


Public Class HLSColor

    Private ReadOnly isUndefined As Boolean
    Public ReadOnly Property A As Byte
    Public ReadOnly Property H As Single
    Public ReadOnly Property L As Single
    Public ReadOnly Property S As Single

    Public Sub New(color As Color)
        A = color.A
        Dim R As Integer = color.R
        Dim G As Integer = color.G
        Dim B As Integer = color.B
        Dim MAX As Single = Math.Max(R, Math.Max(G, B))
        Dim MIN As Single = Math.Min(R, Math.Min(G, B))
        If MIN = MAX Then
            isUndefined = True
        ElseIf MIN = B Then
            H = 60 * ((G - R) / (MAX - MIN)) + 60
        ElseIf MIN = R Then
            H = 60 * ((B - G) / (MAX - MIN)) + 180
        Else
            H = 60 * ((R - B) / (MAX - MIN)) + 300
        End If
        L = (MAX + MIN) / 2
        S = MAX - MIN
    End Sub

    Public Sub New(A As Byte, H As Single, L As Single, S As Single)
        Me.A = A
        Me.H = H
        Me.L = L
        Me.S = S
    End Sub

    Public Function ToColor() As Color
        Dim R, G, B As Single
        Dim MAX As Single = L + S / 2
        Dim MIN As Single = L - S / 2
        If isUndefined Then
            R = MAX
            G = MAX
            B = MAX
        ElseIf H < 60 Then
            R = MAX
            G = MIN + (MAX - MIN) * (H / 60)
            B = MIN
        ElseIf H < 120 Then
            R = MIN + (MAX - MIN) * ((120 - H) / 60)
            G = MAX
            B = MIN
        ElseIf H < 180 Then
            R = MIN
            G = MAX
            B = MIN + (MAX - MIN) * ((H - 120) / 60)
        ElseIf H < 240 Then
            R = MIN
            G = MIN + (MAX - MIN) * ((240 - H) / 60)
            B = MAX
        ElseIf H < 300 Then
            R = MIN + (MAX - MIN) * ((H - 240) / 60)
            G = MIN
            B = MAX
        Else
            R = MAX
            G = MIN
            B = MIN + (MAX - MIN) * ((360 - H) / 60)
        End If
        Return Color.FromArgb(A, CInt(R), CInt(G), CInt(B))
    End Function

End Class

Public Class Form1

    Protected Overrides Sub OnPaint(e As PaintEventArgs)
        Dim rect As New Rectangle(10, 10, 20, 20)
        For count As Integer = 3 To 20
            Dim hlsColor As New HLSColor(Color.Red)
            Dim A As Byte = hlsColor.A
            Dim H As Single = hlsColor.H
            Dim L As Single = hlsColor.L
            Dim S As Single = hlsColor.S
            For i As Integer = 1 To count
                Dim color As Color = New HLSColor(A, H, L, S).ToColor()
                Using b As New SolidBrush(color)
                    e.Graphics.FillRectangle(b, rect)
                End Using
                H += 360 / count
                While H >= 360
                    H -= 360
                End While
                rect.X += 30
            Next
            rect.X = 10
            rect.Y += 30
        Next
    End Sub

End Class

引用返信 編集キー/
■100142 / inTopicNo.6)  Re[4]: 異なるカラーを自動で割り振る方法
□投稿者/ KOZ (262回)-(2022/07/07(Thu) 01:07:33)
No100141 (KOZ) に返信

うーん、Color.Red とかだとうまく変換できないですね。
何か転記ミスしてるかも。
目がショボショボしてきたので、またの機会に(^_^;)
引用返信 編集キー/
■100143 / inTopicNo.7)  Re[3]: 異なるカラーを自動で割り振る方法
□投稿者/ 魔界の仮面弁士 (3428回)-(2022/07/07(Thu) 02:04:59)
No100139 (伝説のカレー さん) に返信
> HSL色空間で計算すれば色相だけ変えられます

System.Drawing.Color 構造体には、
 HSL の色相値を得るための GetHue メソッド
 HSL の彩度値を得るための GetSaturation メソッド
 HSL の輝度値を得るための GetBrightness メソッド
が用意されていますが、RGB → HSL 変換ができるだけで、
逆変換のためには、自前で計算するしかないんですよね。
https://www.ipentec.com/document/csharp-color-to-hsb-value
https://dobon.net/vb/dotnet/graphics/hsv.html

引用返信 編集キー/
■100145 / inTopicNo.8)  Re[4]: 異なるカラーを自動で割り振る方法
□投稿者/ KOZ (263回)-(2022/07/07(Thu) 07:30:37)
2022/07/07(Thu) 07:31:16 編集(投稿者)
No100143 (魔界の仮面弁士 さん) に返信
> 逆変換のためには、自前で計算するしかないんですよね。
> https://www.ipentec.com/document/csharp-color-to-hsb-value
> https://dobon.net/vb/dotnet/graphics/hsv.html

あら、どぼんさんのとこにあったんですね。
車輪の再発明をしてしまった。

Public Shared Function FromHSV(h As Single, s As Single, v As Single) As HsvColor
    Return New HsvColor(h, s, v)
End Function

を HsvColor に追加して

Public Class Form1

    Protected Overrides Sub OnPaint(e As PaintEventArgs)
        MyBase.OnPaint(e)
        Dim rect As New Rectangle(10, 10, 20, 20)
        For count As Integer = 3 To 20
            Dim hsvColor As HsvColor = HsvColor.FromRgb(Color.Red)
            Dim H As Single = hsvColor.H
            Dim S As Single = hsvColor.S
            Dim V As Single = hsvColor.V

            For i As Integer = 1 To count
                Dim color As Color = hsvColor.ToRgb(hsvColor.FromHSV(H, S, V))
                Using b As New SolidBrush(color)
                    e.Graphics.FillRectangle(b, rect)
                End Using
                H += (360 / (count + 1))
                While H >= 360
                    H -= 360
                End While
                rect.X += 30
            Next
            rect.X = 10
            rect.Y += 30
        Next
    End Sub

End Class

引用返信 編集キー/
■100146 / inTopicNo.9)  Re[5]: 異なるカラーを自動で割り振る方法
□投稿者/ KOZ (264回)-(2022/07/07(Thu) 08:04:40)
No100142 (KOZ さん) に返信
> うーん、Color.Red とかだとうまく変換できないですね。
> 何か転記ミスしてるかも。

修正しておきました。m(_ _;)m
引用返信 編集キー/
■100150 / inTopicNo.10)  Re[5]: 異なるカラーを自動で割り振る方法
□投稿者/ 寺 (2回)-(2022/07/07(Thu) 11:52:55)
ありがとうございます。

実行しようとしてみたのですが
HSVとHSLが混在しており、
エラーが出てしまいました。

100141だけだとエラーは出ないのですが、
100145で置き換えるのが正しいのですよね?

どのように修正すればよろしいでしょうか?
引用返信 編集キー/
■100151 / inTopicNo.11)  Re[6]: 異なるカラーを自動で割り振る方法
□投稿者/ 魔界の仮面弁士 (3429回)-(2022/07/07(Thu) 11:57:39)
No100150 (寺 さん) に返信
> HSVとHSLが混在しており、
> エラーが出てしまいました。
> 100141だけだとエラーは出ないのですが、
> 100145で置き換えるのが正しいのですよね?

No100141 は「Public Class HLSColor」が必要で、
No100145 は「Public Class HsvColor」が必要です。

HsvColor クラスの実装は、リンク先の どぼん! さんのサイトに掲載されています。
引用返信 編集キー/
■100152 / inTopicNo.12)  Re[7]: 異なるカラーを自動で割り振る方法
□投稿者/ KOZ (267回)-(2022/07/07(Thu) 12:34:28)
No100151 (魔界の仮面弁士 さん) に返信
>
> No100141 は「Public Class HLSColor」が必要で、
> No100145 は「Public Class HsvColor」が必要です。
>
> HsvColor クラスの実装は、リンク先の どぼん! さんのサイトに掲載されています。
ですます。(^_^;)

どちらも使い方は同じで、たとえば HLSColor の場合、赤起点だと H はゼロになります。
3 本の線が欲しいときは、360 を 3 で割って、120 を求め、ゼロから加算していき、H=0, H=120, H=240 の色を取ることになります。
引用返信 編集キー/
■100164 / inTopicNo.13)  Re[8]: 異なるカラーを自動で割り振る方法
□投稿者/ 寺 (4回)-(2022/07/07(Thu) 18:40:28)
まさにこれでした。
どうもありがとうございました。

解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -