ブラシを一度だけ宣言したい場合は、グラデーションが適用される直前に変換を指定できます。変換を使用すると、 で指定できるコンストラクター引数の多くがオーバーライドされることに注意してくださいLinearGradientBrush
。
LinearGradientBrush.Transform プロパティ (System.Drawing.Drawing2D)
変換を変更するには、目的のマトリックス操作に対応するブラシ オブジェクトのメソッドを呼び出します。行列演算は可換ではないため、順序が重要であることに注意してください。目的のために、おそらく、長方形の各レンディションに対して、スケール、回転、オフセット/移動の順序でそれらを実行することをお勧めします。
LinearGradientBrush.ResetTransform メソッド @ MSDN
LinearGradientBrush.ScaleTransform メソッド (Single、Single、MatrixOrder) @ MSDN
LinearGradientBrush.RotateTransform メソッド (Single、MatrixOrder) @ MSDN
LinearGradientBrush.TranslateTransform メソッド (Single、Single、MatrixOrder) @ MSDN
システム レベルの描画ツールにはグラデーション ブラシのストック定義が実際には含まれていないことに注意してください。そのため、複数のブラシを作成することにパフォーマンス上の懸念がある場合、多数のグラデーション ブラシを作成しても、GDI+/システムのオーバーヘッド以上のコストはかからないはずです。グラデーションとスタイリングを定義するために必要なデータを保持する.Drawing。変換を介してブラシをカスタマイズするために必要な数学に飛び込むことなく、必要に応じて四角形ごとにブラシを作成するのと同じくらいうまくいくかもしれません。
ブラシ関数 (Windows) @ MSDN
WinForms アプリでテストできるコード例を次に示します。このアプリは、45 度のグラデーションを使用してグラデーション ブラシでタイルをペイントし、タイルの最大寸法にスケーリングします (単純に計算されます)。値と変換をいじると、自明でないグラデーション定義がある場合、すべての四角形に変換を設定する手法を使用する価値がないことに気付くかもしれません。それ以外の場合、変換はワールド レベルで適用されることに注意してください。GDI の世界では、y 軸が上下逆になっていますが、デカルトの数学の世界では、下から上に並べられています。これにより、角度も時計回りに適用されますが、三角法では、上向きの y 軸の値が増加するにつれて、角度は反時計回りに進みます。
using System.Drawing.Drawing2D;
namespace TestMapTransform
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
Rectangle rBrush = new Rectangle(0,0,1,1);
Color startColor = Color.DarkRed;
Color endColor = Color.White;
LinearGradientBrush br = new LinearGradientBrush(rBrush, startColor, endColor, LinearGradientMode.Horizontal);
int wPartitions = 5;
int hPartitions = 5;
int w = this.ClientSize.Width;
w = w - (w % wPartitions) + wPartitions;
int h = this.ClientSize.Height;
h = h - (h % hPartitions) + hPartitions;
for (int hStep = 0; hStep < hPartitions; hStep++)
{
int hUnit = h / hPartitions;
for (int wStep = 0; wStep < wPartitions; wStep++)
{
int wUnit = w / wPartitions;
Rectangle rTile = new Rectangle(wUnit * wStep, hUnit * hStep, wUnit, hUnit);
if (e.ClipRectangle.IntersectsWith(rTile))
{
int maxUnit = wUnit > hUnit ? wUnit : hUnit;
br.ResetTransform();
br.ScaleTransform((float)maxUnit * (float)Math.Sqrt(2d), (float)maxUnit * (float)Math.Sqrt(2d), MatrixOrder.Append);
br.RotateTransform(45f, MatrixOrder.Append);
br.TranslateTransform(wUnit * wStep, hUnit * hStep, MatrixOrder.Append);
e.Graphics.FillRectangle(br, rTile);
br.ResetTransform();
}
}
}
}
private void Form1_Resize(object sender, EventArgs e)
{
this.Invalidate();
}
}
}
出力のスナップショットを次に示します。