![]() | |
![]() |
| | Thread Tools | Search this Thread | Display Modes |
#1
| |||
| |||
|
#2
| |||
| |||
|
|
I am having trouble, I think, dealing with GDI+ transformations. I have read all that I can find on the subject, (including Bob Powell's excellent FAQ and primer), but I appear to be missing some fundamental or I just don't get it. What I am attempting to do is illustrated in the VB.NET code shown below, but can be summarised as follows: The coordinates for 2 polygons are specified in metres. For those who are really interested they are actually in respect of the New Zealand Map Grid projection. The origin for both polygons is the bottom left corner. It seems to me that I should be able to define a series of tranformations that will do the whole job rather than having to execute a number of steps where I have to re-process the data a number of times. If anyone can help me to understand this better then I will be very grateful. The code .... Dim m_polygons As List(Of List(Of PointF)) Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load m_polygons = New List(Of List(Of PointF)) m_polygons.Add(New List(Of PointF)(New PointF() {New PointF(2727597.42, 6106293.737), New PointF(2727652.434, 6106195.849), New PointF(2727694.003, 6106123.506), New PointF(2727763.29, 6106001.696), New PointF(2727788.363, 6105957.847), New PointF(2727798.628, 6105940.072), New PointF(2727910.42, 6106001.514), New PointF(2727993.563, 6106049.8), New PointF(2727902.583, 6106207.581), New PointF(2727810.943, 6106366.357), New PointF(2727775.272, 6106428.556), New PointF(2727690.896, 6106574.859), New PointF(2727654.082, 6106638.411), New PointF(2727646.77, 6106590.058), New PointF(2727617.795, 6106416.15), New PointF(2727610.378, 6106371.589), New PointF(2727597.42, 6106293.737)})) m_polygons.Add(New List(Of PointF)(New PointF() {New PointF(2727597.42, 6106293.737), New PointF(2727569.482, 6106122.587), New PointF(2727548.613, 6106002.36), New PointF(2727524.538, 6105854.383), New PointF(2727516.172, 6105802.327), New PointF(2727788.363, 6105957.847), New PointF(2727763.29, 6106001.696), New PointF(2727694.003, 6106123.506), New PointF(2727652.434, 6106195.849), New PointF(2727597.42, 6106293.737)})) End Sub Private Sub Panel1_Paint(ByVal sender As Object, ByVal e As PaintEventArgs) Handles Panel1.Paint ' Construct a 'canvas' being the bounds of the target 'surface' with a 5 pixel buffer at each edge. Dim _canvas As RectangleF = Panel1.Bounds _canvas.Inflate(-10, -10) ' Construct a GraphicsPath object comprising the shapes to be drawn , using the raw data (in metres). Dim _gp As New GraphicsPath For Each _polygon As List(Of PointF) In m_polygons _gp.AddPolygon(_polygon.ToArray) Next ' Retrieve a rectangle being the bounds of the GraphicsPath object. Dim _extent As RectangleF = _gp.GetBounds() ' Compute the 'scale factor' being the number of pixels required to represent 1 metre. ' This must take into account the orientation of both the 'canvas' and the GraphicsPath object. Dim _scalefactor As Single = Math.Min(_canvas.Width / _extent.Width, _canvas.Height / _extent.Height) ' Now scale the raw data using the computed 'scale factor' and construct a new GraphicsPath object. Dim _polygons As New List(Of List(Of PointF)) _gp = New GraphicsPath For Each _polygon As List(Of PointF) In m_polygons Dim _newpolygon As New List(Of PointF) For Each _pointf As PointF In _polygon _newpolygon.Add(New PointF(_pointf.X * _scalefactor, _pointf.Y * _scalefactor)) Next _polygons.Add(_newpolygon) _gp.AddPolygon(_newpolygon.ToArray) Next ' Retrieve a rectangle being the bounds of the new GraphicsPath object. _extent = _gp.GetBounds() ' 'Move' the center of the graphics viewport so that the GraphicsPath object is centered in the target 'surface'. e.Graphics.TranslateTransform((Panel1.Width - _extent.Width) / 2, (Panel1.Height - _extent.Height) / 2) ' Now 'move' the data relative to the viewport and construct a new GraphicsPath object. _gp = New GraphicsPath For Each _polygon As List(Of PointF) In _polygons For _i As Integer = 0 To _polygon.Count - 1 _polygon(_i) = New PointF(_polygon(_i).X - _extent.X, _polygon(_i).Y - _extent.Y) Next _gp.AddPolygon(_polygon.ToArray) Next ' The 'origin' of the raw data is the lower left corner rather than the top left corner. ' The new GraphicsPath object needs to have the Y axis reversed so that it is the right way up. ' It is imperative that only the data is affected and not the 'canvas' itself. _gp.Transform(New Matrix(1, 0, 0, -1, 0, _extent.Height)) ' Finally, draw the GraphicsPath object. Using _pen As New Pen(Color.Black) e.Graphics.DrawPath(_pen, _gp) End Using _gp.Dispose() End Sub Private Sub Panel1_Resize(ByVal sender As Object, ByVal e As EventArgs) Handles Panel1.Resize Panel1.Invalidate() End Sub .... |
#3
| |||
| |||
|
|
Hi Stephany, I had a play with this (albeit in C#) is this the sort of thing you want to do? Bob. (code after my sig) -- -- Bob Powell [MVP] Visual C#, System.Drawing Ramuseco Limited .NET consulting http://www.ramuseco.com Find great Windows Forms articles in Windows Forms Tips and Tricks http://www.bobpowell.net/tipstricks.htm Answer those GDI+ questions with the GDI+ FAQ http://www.bobpowell.net/faqmain.htm All new articles provide code in C# and VB.NET. Subscribe to the RSS feeds provided and never miss a new article. --------------------------------------------------------------------------- public partial class Form1 : Form { List<List<PointF>> polys=new List<List<PointF>>(); List<GraphicsPath> paths = new List<GraphicsPath>(); public Form1() { InitializeComponent(); this.SetStyle(ControlStyles.ResizeRedraw, true); List<PointF> poly1 = new List<PointF>(new PointF[]{ new PointF(10000f,10000f), new PointF(110000f,10000f), new PointF(110000f,110000f), new PointF(10000f,110000f), new PointF(10000f,10000f) }); //polys.Add(poly1); poly1=new List<PointF>(new PointF[]{ new PointF(2727597.42f, 6106293.737f), new PointF(2727652.434f, 6106195.849f), new PointF(2727694.003f, 6106123.506f), new PointF(2727763.29f, 6106001.696f), new PointF(2727788.363f, 6105957.847f), new PointF(2727798.628f, 6105940.072f), new PointF(2727910.42f, 6106001.514f), new PointF(2727993.563f, 6106049.8f), new PointF(2727902.583f, 6106207.581f), new PointF(2727810.943f, 6106366.357f), new PointF(2727775.272f, 6106428.556f), new PointF(2727690.896f, 6106574.859f), new PointF(2727654.082f, 6106638.411f), new PointF(2727646.77f, 6106590.058f), new PointF(2727617.795f, 6106416.15f), new PointF(2727610.378f, 6106371.589f), new PointF(2727597.42f, 6106293.737f)}); polys.Add(poly1); poly1 = new List<PointF>(new PointF[]{ new PointF(2727597.42f, 6106293.737f), new PointF(2727569.482f, 6106122.587f), new PointF(2727548.613f, 6106002.36f), new PointF(2727524.538f, 6105854.383f), new PointF(2727516.172f, 6105802.327f), new PointF(2727788.363f, 6105957.847f), new PointF(2727763.29f, 6106001.696f), new PointF(2727694.003f, 6106123.506f), new PointF(2727652.434f, 6106195.849f), new PointF(2727597.42f, 6106293.737f)}); polys.Add(poly1); foreach (List<PointF> poly in polys) { GraphicsPath gp = new GraphicsPath(); gp.AddPolygon(poly.ToArray()); paths.Add(gp); } } protected override void OnPaint(PaintEventArgs e) { RectangleF pathbounds = paths[0].GetBounds(); foreach (GraphicsPath pth in this.paths) { pathbounds = RectangleF.Union(pathbounds, pth.GetBounds()); } Matrix transform = new Matrix(1,0,0,-1,0,this.ClientRectangle.Height); //reverse the Y axis transform.Scale(0.8f*(float)ClientRectangle.Width/pathbounds.Width, 0.8f*(float)ClientRectangle.Width/pathbounds.Width,MatrixOrder.Prepend); transform.Translate(-pathbounds.X, -pathbounds.Y, MatrixOrder.Prepend); e.Graphics.Transform = transform; Random r=new Random(); foreach (GraphicsPath pth in this.paths) { e.Graphics.FillPath(new SolidBrush(Color.FromArgb(r.Next(255),r.Next(255), r.Next(255))), pth); } base.OnPaint(e); } } "Stephany Young" <noone@localhost> wrote in message news:evohzeBTIHA.6060 (AT) TK2MSFTNGP05 (DOT) phx.gbl... I am having trouble, I think, dealing with GDI+ transformations. I have read all that I can find on the subject, (including Bob Powell's excellent FAQ and primer), but I appear to be missing some fundamental or I just don't get it. What I am attempting to do is illustrated in the VB.NET code shown below, but can be summarised as follows: The coordinates for 2 polygons are specified in metres. For those who are really interested they are actually in respect of the New Zealand Map Grid projection. The origin for both polygons is the bottom left corner. It seems to me that I should be able to define a series of tranformations that will do the whole job rather than having to execute a number of steps where I have to re-process the data a number of times. If anyone can help me to understand this better then I will be very grateful. The code .... Dim m_polygons As List(Of List(Of PointF)) Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load m_polygons = New List(Of List(Of PointF)) m_polygons.Add(New List(Of PointF)(New PointF() {New PointF(2727597.42, 6106293.737), New PointF(2727652.434, 6106195.849), New PointF(2727694.003, 6106123.506), New PointF(2727763.29, 6106001.696), New PointF(2727788.363, 6105957.847), New PointF(2727798.628, 6105940.072), New PointF(2727910.42, 6106001.514), New PointF(2727993.563, 6106049.8), New PointF(2727902.583, 6106207.581), New PointF(2727810.943, 6106366.357), New PointF(2727775.272, 6106428.556), New PointF(2727690.896, 6106574.859), New PointF(2727654.082, 6106638.411), New PointF(2727646.77, 6106590.058), New PointF(2727617.795, 6106416.15), New PointF(2727610.378, 6106371.589), New PointF(2727597.42, 6106293.737)})) m_polygons.Add(New List(Of PointF)(New PointF() {New PointF(2727597.42, 6106293.737), New PointF(2727569.482, 6106122.587), New PointF(2727548.613, 6106002.36), New PointF(2727524.538, 6105854.383), New PointF(2727516.172, 6105802.327), New PointF(2727788.363, 6105957.847), New PointF(2727763.29, 6106001.696), New PointF(2727694.003, 6106123.506), New PointF(2727652.434, 6106195.849), New PointF(2727597.42, 6106293.737)})) End Sub Private Sub Panel1_Paint(ByVal sender As Object, ByVal e As PaintEventArgs) Handles Panel1.Paint ' Construct a 'canvas' being the bounds of the target 'surface' with a 5 pixel buffer at each edge. Dim _canvas As RectangleF = Panel1.Bounds _canvas.Inflate(-10, -10) ' Construct a GraphicsPath object comprising the shapes to be drawn , using the raw data (in metres). Dim _gp As New GraphicsPath For Each _polygon As List(Of PointF) In m_polygons _gp.AddPolygon(_polygon.ToArray) Next ' Retrieve a rectangle being the bounds of the GraphicsPath object. Dim _extent As RectangleF = _gp.GetBounds() ' Compute the 'scale factor' being the number of pixels required to represent 1 metre. ' This must take into account the orientation of both the 'canvas' and the GraphicsPath object. Dim _scalefactor As Single = Math.Min(_canvas.Width / _extent.Width, _canvas.Height / _extent.Height) ' Now scale the raw data using the computed 'scale factor' and construct a new GraphicsPath object. Dim _polygons As New List(Of List(Of PointF)) _gp = New GraphicsPath For Each _polygon As List(Of PointF) In m_polygons Dim _newpolygon As New List(Of PointF) For Each _pointf As PointF In _polygon _newpolygon.Add(New PointF(_pointf.X * _scalefactor, _pointf.Y * _scalefactor)) Next _polygons.Add(_newpolygon) _gp.AddPolygon(_newpolygon.ToArray) Next ' Retrieve a rectangle being the bounds of the new GraphicsPath object. _extent = _gp.GetBounds() ' 'Move' the center of the graphics viewport so that the GraphicsPath object is centered in the target 'surface'. e.Graphics.TranslateTransform((Panel1.Width - _extent.Width) / 2, (Panel1.Height - _extent.Height) / 2) ' Now 'move' the data relative to the viewport and construct a new GraphicsPath object. _gp = New GraphicsPath For Each _polygon As List(Of PointF) In _polygons For _i As Integer = 0 To _polygon.Count - 1 _polygon(_i) = New PointF(_polygon(_i).X - _extent.X, _polygon(_i).Y - _extent.Y) Next _gp.AddPolygon(_polygon.ToArray) Next ' The 'origin' of the raw data is the lower left corner rather than the top left corner. ' The new GraphicsPath object needs to have the Y axis reversed so that it is the right way up. ' It is imperative that only the data is affected and not the 'canvas' itself. _gp.Transform(New Matrix(1, 0, 0, -1, 0, _extent.Height)) ' Finally, draw the GraphicsPath object. Using _pen As New Pen(Color.Black) e.Graphics.DrawPath(_pen, _gp) End Using _gp.Dispose() End Sub Private Sub Panel1_Resize(ByVal sender As Object, ByVal e As EventArgs) Handles Panel1.Resize Panel1.Invalidate() End Sub .... |
![]() |
| Thread Tools | Search this Thread |
| Display Modes | |
| |