È possibile specificare una trasformazione al momento appena prima dell'applicazione del gradiente se si desidera dichiarare il pennello una sola volta. Si noti che l'utilizzo delle trasformazioni sovrascrive molti degli argomenti del costruttore che possono essere specificati su un LinearGradientBrush
.
LinearGradientBrush.Transform Property (System.Drawing.Drawing2D)
Per modificare la trasformazione, chiamare i metodi sull'oggetto pennello corrispondenti alle operazioni di matrice desiderati. Nota che le operazioni con le matrici non sono commutative, quindi l'ordine è importante. Per i tuoi scopi, probabilmente vorrai eseguirli in questo ordine per ogni versione dei tuoi rettangoli: Scala, Ruota, Offset/Traduci.
LinearGradientBrush.ResetTransform Method @ MSDN
LinearGradientBrush.ScaleTransform Method (Single, Single, MatrixOrder) @ MSDN
LinearGradientBrush.RotateTransform Method (Single, MatrixOrder) @ MSDN
LinearGradientBrush.TranslateTransform Method (Single, Single, MatrixOrder) @ MSDN
Si noti che gli strumenti di disegno a livello di sistema in realtà non contiene una definizione magazzino per pennello sfumato, quindi se avete problemi di prestazioni sulla creazione di più pennelli, la creazione di una moltitudine di pennelli sfumati non dovrebbe costare più del sovraccarico di GDI +/System.Drawin g mantenere i dati richiesti per definire il gradiente e lo stile. Potrebbe essere altrettanto utile creare un pennello per rettangolo, se necessario, senza dover immergersi nei calcoli necessari per personalizzare il pennello tramite la trasformazione.
Brush Functions (Windows) @ MSDN
Ecco un esempio di codice è possibile testare in un'applicazione WinForms. Questa applicazione dipinge le tessere con un pennello sfumato utilizzando un gradiente di 45 gradi, ridimensionato alla dimensione più grande della piastrella (calcolato in modo ingenuo). Se si gioca con i valori e le trasformazioni, è possibile che non valga la pena usare la tecnica che imposta una trasformazione per tutti i rettangoli se si hanno definizioni di sfumature non banali. Altrimenti, ricorda che le tue trasformazioni sono applicate a livello mondiale e, nel mondo GDI, l'asse delle ordinate è capovolto, mentre nel mondo matematico cartesiano è ordinato dal basso verso l'alto. Questo fa sì che l'angolo venga applicato in senso orario, mentre nella trigonometria, l'angolo avanza in senso antiorario aumentando il valore per un asse y rivolto verso l'alto.
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();
}
}
}
Ecco un'istantanea dell'output:
che non aiuta contro la mia paura di creare un pennello sfumato per ogni rettangolo. In realtà ho 2 pennelli che devo usare per dipingere 1000 rettangoli. – Eugen
Scusa amico, ma penso che tu non abbia un'altra opzione. Se riscontri problemi di prestazioni, puoi migliorarlo utilizzando i thread. Puoi ridurre il tempo con quello. Quanto tempo ci vuole per riempire tutti quei rettangoli ora creando un LinearGradientBrush per rettangolo? – Andres
Non ho ancora testato, speravo solo di avere lo stesso processo di creazione dei pennelli come in WPF e ho avuto l'idea che mi manchi qualcosa. Ma sembra che questo sia l'unico modo. – Eugen