Wrox Programmer Forums
|
BOOK: Visual Basic 2005 Programmer's Reference
This is the forum to discuss the Wrox book Visual Basic 2005 Programmer's Reference by Rod Stephens; ISBN: 9780764571985
Welcome to the p2p.wrox.com Forums.

You are currently viewing the BOOK: Visual Basic 2005 Programmer's Reference section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old May 22nd, 2006, 05:28 AM
Authorized User
 
Join Date: Mar 2006
Posts: 18
Thanks: 0
Thanked 0 Times in 0 Posts
Default Graphics

So far in my programming 'career' I have managed to avoid graphics. Mostly because I have not needed it but also because it is an alien area to me. Now I need to do something and would appreciated any pointers on how/where to start. I am sure this has been done many many times before :)

The specification outline is

I have a series of objects - each of which is a rectangle described in terms of it's type, placement point, width, length and heading (i.e. the angle at which is is placed). The co-ordinate system is latitude ( +90 to -90) and longitude (+180 to -180), width and length are described in meters.

I want to be able first to draw these objects onto a space so that their size and relationships are accurately represented.

I want to be able to zoom in and out on the objects and re center the visible area on different objects

I want to be able to select and object and bring up a window describing the object.

That is the first level I want to get to

Later I would like to be able to move the object by drag and drop, and rotate it about it's placement point. I do NOT resize it. I would then like to be able to add new objects into the area.

All pointers gratefully received




Jon Masterson
__________________
Jon Masterson
 
Old May 26th, 2006, 08:31 AM
Rod Stephens's Avatar
Wrox Author
 
Join Date: Jan 2006
Posts: 647
Thanks: 2
Thanked 96 Times in 95 Posts
Default

First note that your coordinates span the entire globe which is a sphere not a rectangle so if you simply map this data to a rectangle you'll get deformed data similar to what you see on a flat map of the world. There are projection methods that map patches from spherical coordinates onto a flat surface but I havn't done that. You'll need to look around some cartography Web sites for those sorts of algorithms.

The Graphics object supports transformations that can represent translation, scaling, and rotation. The trick is to figure out hwo to translate and scale so your data appears where you want it. Here's a subroutine that sets the transformation for a Graphics object to map data coordinates with corners at (data_ul_x, data_ul_y)-(data_lr_x, data_lr_y) to the device coordinates (dev_ul_x, dev_ul_y)-(dev_lr_x, data_lr_y).

Private Sub ScaleControl(ByVal gr As Graphics, _
 ByVal data_ul_x As Single, ByVal data_ul_y As Single, _
 ByVal data_lr_x As Single, ByVal data_lr_y As Single, _
 ByVal dev_ul_x As Single, ByVal dev_ul_y As Single, _
 ByVal dev_ll_x As Single, ByVal dev_ll_y As Single)
    ' Start from scratch.
    gr.ResetTransform()

    ' Move (data_ul_x, data_ul_y) to the origin.
    gr.TranslateTransform(-data_ul_x, -data_ul_y, _
        MatrixOrder.Append)

    ' Scale so the data rectangle's width and height
    ' match those of the device rectangle.
    gr.ScaleTransform( _
        (dev_ll_x - dev_ul_x) / (data_lr_x - data_ul_x), _
        (dev_ll_y - dev_ul_y) / (data_lr_y - data_ul_y), _
        MatrixOrder.Append)

    ' Move the origin to (dev_ul_x, dev_ul_y).
    gr.TranslateTransform(dev_ul_x, dev_ul_y, _
        MatrixOrder.Append)
End Sub

For your example, the data coordinates would be the lat and long of the area you want to display. The device coordinates would be the corners of the PictureBox or whatever control you are drawing on.

You should pick the data bounds so the area's width/height ratio is the same as the control's width/height ratio so the data isn't stretched or squashed.

Rotating objects is not much harder than all this. The idea is: translate the object's center of rotation (for example, you might rotate around its middle) to the origin, rotate it, and then translate the origin back to the original center of rotation. So to draw a map with a rotated object:

    1. Use ScaleControl to set up the map's basic transformation.
    2. Draw the stuff that doesn't need rotation.
    3. Save the transformation. I think you can store the Graphics object's Transform property. Or there's a method that essentially makes a checkpoint that you can later return to.
    4. For each object that needs rotation:
        A. Add a translation to move the center of rotation to the origin.
        B. Add a rotation.
        C. Add the inverse of the translation for step 4A.
        D. Draw the object.
        E. Restore the transformation you saved in step 3.

Each step isn't too complicated but taken all together it can be pretty confusing.

I hope that helps.


Rod
RodStephens@vb-helper.com
Author of "Visual Basic 2005 Programmer's Reference"
http://www.vb-helper.com/vb_prog_ref.htm
 
Old May 26th, 2006, 11:10 AM
Authorized User
 
Join Date: Mar 2006
Posts: 18
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Thanks Rod

That is a big help plus I have re-read the section on Graphics in the book. And yes I am finding it confusing in totality so I will need to build it up bit by bit like a prototype :D.

I do have the algorithms for spherical geometry since my program uses them to calculate distance and bearing between two points and also I can determine the co-ordinates of a far point based on bearing and distance. The actual area over which the program needs to operate is small (normally no more than 3000 meters square) but it can be anywhere on the earth.

I am wondering if I would do better to turn everything from latitude and longitude into x & y distances in meters from a reference point before I start. My program can do that as well taking sherical geometry into account.


Jon Masterson
 
Old May 27th, 2006, 07:24 AM
Rod Stephens's Avatar
Wrox Author
 
Join Date: Jan 2006
Posts: 647
Thanks: 2
Thanked 96 Times in 95 Posts
Default

Hi Jon,

Yes, it might be best to convert into x & y so you have a flat coordinate system to draw from. Otherwise things get really weird near the poles. Imagine plotting the North Pole in the center of the form and then being faced with several points that all have latitude < 90. You'd need to make the conversion at that point anyway.


Rod
RodStephens@vb-helper.com
Author of "Visual Basic 2005 Programmer's Reference"
http://www.vb-helper.com/vb_prog_ref.htm

Sign up for the free VB Helper Newsletters at http://www.vb-helper.com/newsletter.html
 
Old May 27th, 2006, 07:41 AM
Authorized User
 
Join Date: Mar 2006
Posts: 18
Thanks: 0
Thanked 0 Times in 0 Posts
Default

I'll keep you posted how I get on :D or not as the case maybe :(


Jon Masterson
 
Old May 29th, 2006, 07:31 AM
Authorized User
 
Join Date: Mar 2006
Posts: 18
Thanks: 0
Thanked 0 Times in 0 Posts
Default

OK I thought I might be seeing how some of this works but I am clearly not. Here were my working premises

1) the graphics object stores information about objects in world co-ordinates so it represents a big flat area and anything placed on it actually stays where it is.

2) the display area (for want of a better word) is the bit you can see - for example my picturebox.

Now what I was hoping was that I could set up a graphics object and populate an array with my rectangles - each is a class with it's size and the ability to draw itself (a draw method). For a test I set up a randomizer to create 25 rectangles of varying sizes and placed them using co-ordinates which could be bigger than my picturebox (I have not fiddled with units so I assume everything is in pixels). I can use a button to generate a random set of boxes, and invalidate the picturebox so they get drawn again. This works and I get random boxes drawn, but just those that fit into the picturebox co-ordinates

Now what I want to do is use navigation buttons to move the window(picturebox) around the graphics object by using translateTransform. OK so I think my simplistic view of things is falling apart here - I guess that actually the size of my graphics object (since it is taken from the picturebox is only the size of the picture box. I have a couple more buttons which I was hoping to use to zoom in and out using the scaleTransform but.......

Am I anywhere near the right track - do I need to create some other sort of graphics object to contain my boxes or am I only going to be able to draw what fits in the pictureBox? I have started to read about graphicContainers and that you can do scaling etc in them, but again I am not sure if that is correct.

Thank you for your patience :)


Jon Masterson
 
Old May 30th, 2006, 07:59 AM
Rod Stephens's Avatar
Wrox Author
 
Join Date: Jan 2006
Posts: 647
Thanks: 2
Thanked 96 Times in 95 Posts
Default

I think you're headed in the right direction. Use the Graphics object's TranslateTransform and ScaleTransform methods to resize and move the world coordinates. For example, this pseudocode scales by a factor of 2 (enlarges):

    gr.ScaleTransform(2, 2, Append)

This one translates so things are drawn shifted 100 units to the right:

    gr.TranslateTransform(100, 0)

This example may help:

    http://www.vb-helper.com/howto_net_set_scale.html


Rod
RodStephens@vb-helper.com
Author of "Visual Basic 2005 Programmer's Reference"
http://www.vb-helper.com/vb_prog_ref.htm

Sign up for the free VB Helper Newsletters at http://www.vb-helper.com/newsletter.html
 
Old May 30th, 2006, 11:08 PM
Authorized User
 
Join Date: Mar 2006
Posts: 18
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Thanks Rod

I have the scaling and scrolling working now - seems to be quite simple once you know how :D I am now moving on to being able to click on a rectangle and select it to bring up information about the object it represents



Jon Masterson
 
Old May 31st, 2006, 07:30 AM
Rod Stephens's Avatar
Wrox Author
 
Join Date: Jan 2006
Posts: 647
Thanks: 2
Thanked 96 Times in 95 Posts
Default

Ah, there's a trick to that, too. The Click and other mouse event handlers give you coordinates in the PictureBox's normal coordinate system. So if you have scaled by a factor of 2, the coordinates you get don't match those on the drawing.

To convert from screen to world coordinates, perform the inverse transformations in reverse order. For example, suppose to draw you used a translation by (-100, 50) and then a scaling of (2, 2). To map the mouse points to world coordinates, scale by (1/2, 1/2) and then translate by (100, -50). Use the Matrix class to perform the transformation.

See this example:

    http://www.vb-helper.com/howto_net_s...ert_scale.html


Rod
RodStephens@vb-helper.com
Author of "Visual Basic 2005 Programmer's Reference"
http://www.vb-helper.com/vb_prog_ref.htm

Sign up for the free VB Helper Newsletters at http://www.vb-helper.com/newsletter.html
 
Old May 31st, 2006, 08:25 AM
Authorized User
 
Join Date: Mar 2006
Posts: 18
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Thanks Rod, I will try that out :)


Jon Masterson





Similar Threads
Thread Thread Starter Forum Replies Last Post
c/c++ graphics hafizmuhammadmushtaq C++ Programming 0 October 19th, 2007 11:33 PM
graphics in c++ himutg C++ Programming 1 December 12th, 2006 08:22 AM
Help on graphics steparths C++ Programming 0 June 30th, 2006 02:09 PM
graphics in C++ MASTER_1st C++ Programming 2 November 28th, 2005 12:02 AM
Graphics Control Dataman Access 2 March 5th, 2004 03:48 PM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.