469,579 Members | 1,089 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,579 developers. It's quick & easy.

Setting a custom coordinate system like VB picturebox.Scale

Does anyone know how to change the the GDI+ coordinate system like you used
to be able to do in VB6 with the picturebox.scale method. The
picturebox.scale method took an x,y point defining the upper left corner and
a second x,y point defining the lower right corner.

In VB6 the 0,0 location was the upper left like in GDI+, but I could at
least reset it so I could use it with lat/lons. Basically all I want to do
is be able to use the USA lat/lon coordinates to put a circle at a
particular lat/lon.

I've looked at Graphics.RotateTransform and graphics.TranslateTransform, but
they don't seem to do it for me.

-Randy
Nov 20 '05 #1
7 16767
Nak
Hi there,

Have you thought about a simple scaling algorithm to turn your values
into the pixel equivilents? This might be the simplest approach. I wish I
could quote one for you now but I never have been good at maths and it would
require me hunting through zip disks. But I hope the concept helps you as
their isn;t a "scale" method in .NET (That I know of).

Nick.

--
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
"No matter. Whatever the outcome, you are changed."

Fergus - September 5th 2003
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
Nov 20 '05 #2
Randy,
I've looked at Graphics.RotateTransform and graphics.TranslateTransform, but they don't seem to do it for me. You were close ;-)

You need to use Graphics.TranslateTransform along with
Graphics.ScaleTransform.

The trick is to call them in the correct order with the correct parameters.

You need to call TranslateTransform to move the origin to the lower left.
You can use 0 & me.ClientRectangle.Height.

Then you need to call ScaleTransform with 1 & -1 as parameters to flip the y
axis.

Hope this helps
Jay

"Randy Vande Hei" <randyv (at) itol (dot) com> wrote in message
news:uH****************@tk2msftngp13.phx.gbl... Does anyone know how to change the the GDI+ coordinate system like you used to be able to do in VB6 with the picturebox.scale method. The
picturebox.scale method took an x,y point defining the upper left corner and a second x,y point defining the lower right corner.

In VB6 the 0,0 location was the upper left like in GDI+, but I could at
least reset it so I could use it with lat/lons. Basically all I want to do
is be able to use the USA lat/lon coordinates to put a circle at a
particular lat/lon.

I've looked at Graphics.RotateTransform and graphics.TranslateTransform, but they don't seem to do it for me.

-Randy

Nov 20 '05 #3
Nak
Oops, I stand corrected :-)

Nick.

--
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
"No matter. Whatever the outcome, you are changed."

Fergus - September 5th 2003
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
Nov 20 '05 #4
"Randy Vande Hei" <randyv (at) itol (dot) com> wrote in message
news:uH****************@tk2msftngp13.phx.gbl...
Does anyone know how to change the the GDI+ coordinate system like you used to be able to do in VB6 with the picturebox.scale method. The
picturebox.scale method took an x,y point defining the upper left corner and a second x,y point defining the lower right corner.


Well, I sorta missed the old Scale method too so I decided to roll my own
once and for all. IIRC, if you wanted to (predictably) draw arcs in VB.OLD
you
really needed to have "square" canvases so this method always uses the
same scaling factor horizontally and vertically. If you don't want/need that
you
need to slightly change the code so that it calculates and uses 2
scalingfactors:
one for the horizontal scaling and one for the vertical scaling.

Private mWorld2DeviceXfm As New System.Drawing.Drawing2D.Matrix()
Private mDevice2WorldXfm As New System.Drawing.Drawing2D.Matrix()

Public Sub SetScale( _

ByVal xupperleft As Integer, ByVal yupperleft As Integer, _

ByVal xlowerright As Integer, ByVal ylowerright As Integer)

Dim XMirrorFactor As Single = CSng(Sign(xlowerright - xupperleft))

Dim ScaleFactor As Single

If Me.Size.Width < Me.Size.Height Then 'remember to compensate for
non-square canvas !

ScaleFactor = CSng(Me.Size.Width) / Abs(xlowerright - xupperleft)

Else

ScaleFactor = CSng(Me.Size.Height) / Abs(yupperleft - ylowerright)

End If

'construct forward matrix (world coord -> device coord)

mWorld2DeviceXfm.Reset()

mWorld2DeviceXfm.Translate( CSng(-xupperleft), CSng(-yupperleft))

mWorld2DeviceXfm.Scale( XMirrorFactor * ScaleFactor, -1! * ScaleFactor,
MatrixOrder.Append)

'also store inverse matrix (device coord -> world coord) for convenience
when hit-testing

If mWorld2DeviceXfm.IsInvertible() Then

mDevice2WorldXfm = mWorld2DeviceXfm.Clone()

mDevice2WorldXfm.Invert()

End If

End Sub

Please note that this method is taken from a custom control that derives
from

System.Windows.Forms.ScrollableControl. That's why Me.Size is used to
determine the

physical size of the canvas we're drawing on. Your situation may be slightly
different so

take care. Also, try to understand what's going on, it will help you to use
it better.

You can use this method in OnPaint like this:

Protected Overrides Sub OnPaint(ByVal e As
System.Windows.Forms.PaintEventArgs)

Dim xlowleft As Integer, ylowleft As Integer

Dim xupright As Integer, yupright As Integer

MyBase.OnPaint(e)

'calculate your xlowleft, ylowleft, xupright, yupright

......

Me.SetScale( xlowleft, ylowleft, xupright, yupright)

e.Graphics.Transform = mWorld2DeviceXfm

'Draw your stuff on the gr object here

........

End Sub

HTH

eltwo
Nov 20 '05 #5
"Randy Vande Hei" <randyv (at) itol (dot) com> wrote in message
news:uH****************@tk2msftngp13.phx.gbl...
Does anyone know how to change the the GDI+ coordinate system like you used to be able to do in VB6 with the picturebox.scale method. The
picturebox.scale method took an x,y point defining the upper left corner and a second x,y point defining the lower right corner.


Well, I sorta missed the old Scale method too so I decided to roll my own
once and for all. IIRC, if you wanted to (predictably) draw arcs in VB.OLD
you really needed to have "square" canvases so this method always uses the
same scaling factor horizontally and vertically. If you don't want/need that
you need to slightly change the code so that it calculates and uses 2
scalingfactors: one for the horizontal scaling and one for the vertical
scaling.

Private mWorld2DeviceXfm As New System.Drawing.Drawing2D.Matrix()
Private mDevice2WorldXfm As New System.Drawing.Drawing2D.Matrix()

Public Sub SetScale( _
ByVal xupperleft As Integer, ByVal yupperleft As Integer, _
ByVal xlowerright As Integer, ByVal ylowerright As Integer)

Dim XMirrorFactor As Single = CSng(Sign(xlowerright - xupperleft))
Dim ScaleFactor As Single

' compensate for non-square canvas
If Me.Size.Width < Me.Size.Height Then
ScaleFactor = CSng(Me.Size.Width) / Abs(xlowerright - xupperleft)
Else
ScaleFactor = CSng(Me.Size.Height) / Abs(yupperleft - ylowerright)
End If

' construct forward matrix (world coord -> device coord)
mWorld2DeviceXfm.Reset()
mWorld2DeviceXfm.Translate( CSng(-xupperleft), CSng(-yupperleft))
mWorld2DeviceXfm.Scale( XMirrorFactor * ScaleFactor, -1! * ScaleFactor, _
MatrixOrder.Append)

' also store inverse matrix (device coord -> world coord) for
' convenience when hit-testing
If mWorld2DeviceXfm.IsInvertible() Then
mDevice2WorldXfm = mWorld2DeviceXfm.Clone()
mDevice2WorldXfm.Invert()
End If

End Sub
Please note that this method is taken from a custom control that derives
from System.Windows.Forms.ScrollableControl. That's why Me.Size
is used to determine the physical size of the canvas. Your situation may be
different so take care. So now you can use this method in OnPaint like
this:

Protected Overrides Sub OnPaint( ByVal _
e As System.Windows.Forms.PaintEventArgs)

Dim xupleft As Integer, yupleft As Integer
Dim xloright As Integer, yloright As Integer

MyBase.OnPaint(e)

' calculate your xupleft, yupleft, xloright, yloright
.............................
Me.SetScale( xupleft, yupleft, xloright, yloright)
e.Graphics.Transform = mWorld2DeviceXfm

' draw your stuff on the e.Graphics here
..............................

End Sub

HTH

eltwo
Nov 20 '05 #6
That is exactly what I was looking for. Thanks.

I used e.graphics.TranslateTransform (this.ClientRectangle.Width,
this.ClientRectangle.Height) to get the origin over to the bottom right.
So I now have 0,0 a the bottom right. What I need next is to set the upper
limit of x and y so that my plotting can have the affect of zooming.
Again, the vb scale method used to allow this.

i.e. I'd like to be able to fill the window with my plotting regardless of
what size the window is sized to.

-Randy
"Jay B. Harlow [MVP - Outlook]" <Ja********@email.msn.com> wrote in message
news:uC**************@tk2msftngp13.phx.gbl...
Randy,
I've looked at Graphics.RotateTransform and graphics.TranslateTransform, but
they don't seem to do it for me.

You were close ;-)

You need to use Graphics.TranslateTransform along with
Graphics.ScaleTransform.

The trick is to call them in the correct order with the correct

parameters.
You need to call TranslateTransform to move the origin to the lower left.
You can use 0 & me.ClientRectangle.Height.

Then you need to call ScaleTransform with 1 & -1 as parameters to flip the y axis.

Hope this helps
Jay

"Randy Vande Hei" <randyv (at) itol (dot) com> wrote in message
news:uH****************@tk2msftngp13.phx.gbl...
Does anyone know how to change the the GDI+ coordinate system like you

used
to be able to do in VB6 with the picturebox.scale method. The
picturebox.scale method took an x,y point defining the upper left corner

and
a second x,y point defining the lower right corner.

In VB6 the 0,0 location was the upper left like in GDI+, but I could at
least reset it so I could use it with lat/lons. Basically all I want to do is be able to use the USA lat/lon coordinates to put a circle at a
particular lat/lon.

I've looked at Graphics.RotateTransform and graphics.TranslateTransform,

but
they don't seem to do it for me.

-Randy


Nov 20 '05 #7
Randy,
You use ScaleTransform to 'zoom' also.

I normally use a ratio of this.ClientSize (which is the same as
this.ClientRectangle.Size) to the size of my drawing. To get the drawing to
fit in the window itself.

You can call ScaleTransform twice, once to flip the drawing, then a second
time to zoom the drawing. Order should not matter.

Hope this helps
Jay
"Randy Vande Hei" <randyv (at) itol (dot) com> wrote in message
news:eE*************@tk2msftngp13.phx.gbl...
That is exactly what I was looking for. Thanks.

I used e.graphics.TranslateTransform (this.ClientRectangle.Width,
this.ClientRectangle.Height) to get the origin over to the bottom right.
So I now have 0,0 a the bottom right. What I need next is to set the upper limit of x and y so that my plotting can have the affect of zooming.
Again, the vb scale method used to allow this.

i.e. I'd like to be able to fill the window with my plotting regardless of what size the window is sized to.

-Randy
"Jay B. Harlow [MVP - Outlook]" <Ja********@email.msn.com> wrote in message news:uC**************@tk2msftngp13.phx.gbl...
Randy,
I've looked at Graphics.RotateTransform and graphics.TranslateTransform,
but
they don't seem to do it for me. You were close ;-)

You need to use Graphics.TranslateTransform along with
Graphics.ScaleTransform.

The trick is to call them in the correct order with the correct

parameters.

You need to call TranslateTransform to move the origin to the lower left.
You can use 0 & me.ClientRectangle.Height.

Then you need to call ScaleTransform with 1 & -1 as parameters to flip the y
axis.

Hope this helps
Jay

"Randy Vande Hei" <randyv (at) itol (dot) com> wrote in message
news:uH****************@tk2msftngp13.phx.gbl...
Does anyone know how to change the the GDI+ coordinate system like you used
to be able to do in VB6 with the picturebox.scale method. The
picturebox.scale method took an x,y point defining the upper left

corner and
a second x,y point defining the lower right corner.

In VB6 the 0,0 location was the upper left like in GDI+, but I could
at least reset it so I could use it with lat/lons. Basically all I want

to do is be able to use the USA lat/lon coordinates to put a circle at a
particular lat/lon.

I've looked at Graphics.RotateTransform and

graphics.TranslateTransform, but
they don't seem to do it for me.

-Randy



Nov 20 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

2 posts views Thread by SirPoonga | last post: by
reply views Thread by Jacob | last post: by
1 post views Thread by K.N.Ranjit | last post: by
reply views Thread by SamSpade | last post: by
1 post views Thread by Ricardo Furtado | last post: by
14 posts views Thread by Roger Withnell | last post: by
reply views Thread by peradino | last post: by
5 posts views Thread by GoGs | last post: by
2 posts views Thread by =?Utf-8?B?Sm9uIFBhcnJ5?= | last post: by
reply views Thread by suresh191 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.