I'm using WinForms to write a visualizer for a simulation. The visualization involves various objects moving around a grid.
So far, I'm using a custom control that extends Panel and doing the custom drawing with the Graphics class during Paint events. However, one irritation is that I'm constantly having to scale things from grid coordinates to the control.DisplayRectangle coordinates (in other words, an object that takes up 2 cells in the grid would take up 2 * (control.DisplayRectangle.Width / horizontalGridWidth) pixels when drawn).
I'm wondering, is there a way to get the Graphics object to do these translations for me so that I can express my drawing in grid coordinates and have it automatically be mapped to the physical coordinates?
It turns out that Matrix was indeed the key (see accepted answer). Here's the code that got it working:
public SimulationPanel() {
this.DoubleBuffered = true;
this.SizeChanged += (o, e) => this.Invalidate();
this.Paint += this.PaintPanel;
}
private void Paint(object sender, PaintEventArgs e) {
e.Graphics.Clear(Color.Black);
var fromRectangle = GetSimulationWorldCoordinates();
var toRectangle = ScaleToFit(fromRectangle, this.DisplayRectangle);
using (var matrix = new Matrix(
fromRectangle,
new[] {
toRectangle.Location,
new Point(toRectangle.Right, toRectangle.Top),
new Point(toRectangle.Left, toRectangle.Bottom),
}))
{
// draw the simulation stuff here using simulation coordinates
e.Graphics.Transform = matrix;
e.Graphics.FillRectangle(Brushes.LightBlue, toRectangle);
e.Graphics.DrawLine(Pens.Red, toRectangle.Location, new Point(toRectangle.Right, toRectangle.Bottom));
}
}
How about this code ?
I use Labels instead of grids because I cannot know your grids.