GDIPLUS: how draw the point Z?-VBForums

# Thread: GDIPLUS: how draw the point Z?

1. ## GDIPLUS: how draw the point Z?

it's easy using\draw the X and Y points. but i don't understand how i can draw the Z. can anyone explain to me how can i draw the point Z?
(i never used the Z and i didn't learned from school)

2. ## Re: GDIPLUS: how draw the point Z?

That's called 3d projection

https://en.wikipedia.org/wiki/3D_projection

4. ## Re: GDIPLUS: how draw the point Z?

Jacob, the thread you point to has a complete different content then you would suspect based on the URL .

5. ## Re: GDIPLUS: how draw the point Z?

i'm sorry but let me ask in a diferent way(i know that the Z it's parallel to X and Y): imagine these(1,2,3)(X,Y,Z). ok.. the X=1 and Y=2... i can draw it using horizontal and vertical pixels. but where is the Z? it's 3, but where i must add it?
do i need convert the Z to X,Y for get the point or something?
(these is my confusion)

6. ## Re: GDIPLUS: how draw the point Z?

You are correct, you have to mimic perspective by calculating the x,y coordinates for z

7. ## Re: GDIPLUS: how draw the point Z?

now i must ask: how can i calculate the X,Y for Z? or i must make my own coordenate scale?

8. ## Re: GDIPLUS: how draw the point Z?

Just to give you the idea: draw a cube on paper.
Have a basic scale on the x and y axes and check the what offsets you need on X and Y to plot Z

9. ## Re: GDIPLUS: how draw the point Z?

Ah shoot. For some reason my phone put the wrong url when i copied and pasted. Its actually my 3d engine in pure vb in my sig. It projects the point in 3d. Also i have some code in vbforums somewhere that also does perspective correct texture mapping as well.

10. ## Re: GDIPLUS: how draw the point Z?

Originally Posted by joaquim
i'm sorry but let me ask in a diferent way(i know that the Z it's parallel to X and Y): imagine these(1,2,3)(X,Y,Z). ok.. the X=1 and Y=2... i can draw it using horizontal and vertical pixels. but where is the Z? it's 3, but where i must add it?
do i need convert the Z to X,Y for get the point or something?
(these is my confusion)
No. As a beginner, you can just ignore the z coordinate when rendering to the screen.

A screen is a flat object. You only specify two dimensions when rendering to it (x, y).

A (z) coordinate is stored and used internally to calculate position changes, but you don't need to "convert" it or do anything special when rendering it to the screen.

11. ## Re: GDIPLUS: how draw the point Z?

Originally Posted by Tanner_H
No. As a beginner, you can just ignore the z coordinate when rendering to the screen.

A screen is a flat object. You only specify two dimensions when rendering to it (x, y).

A (z) coordinate is stored and used internally to calculate position changes, but you don't need to "convert" it or do anything special when rendering it to the screen.
if so, how can i rotate the Z?
on 3D we can rotate te X, Y and Z...
i'm sorry, i can draw a cube using planes, but i don't use 3D points... but i realy need understand more about Z
thanks to all

12. ## Re: GDIPLUS: how draw the point Z?

if so, how can i rotate the Z?
You will still need to use the z value in all of your calculations. But when rendering to the screen, you only need to care about the (x, y) coordinates. (Since screens are two-dimensional, you couldn't use the z value even if you wanted to!)

If you want to test this, I would recommend creating a small sample program. The program should render something easy, like a square.

Then add three scrollbars, one each for rotating around the x, y, or z axis.

Add the basic math required for rotation (there are many websites on this, e.g. http://inside.mines.edu/fs_home/gmur...yAxisRotation/).

Once you have that, this concept will be very easy to demonstrate.

13. ## Re: GDIPLUS: how draw the point Z?

i'm sorry but see these image:

seems that i must create my own coordenates(showing or not show the lines), but how can i calculate perpendiculaire points?
(it's easy add 2 points on a line, but how we can see where is moving to the 2nd point?)

14. ## Re: GDIPLUS: how draw the point Z?

Hi Joaquim, I'll try to answer your question. It's usual to make the Z-axis a line from your eye at right angles to the middle of the screen:

The distance between the eye and the screen is F (which stands for focal length). To start with you could take a fixed value for F, such as 1,000 pixels, but you can "zoom" in or out by changing its value.

The X and Y axes are both at right angles to the Z axis, and the origin (x, y, z = 0, 0, 0) is at the eye (people sometimes place the origin at the screen surface, but it's easy to adjust for that).

Now imagine a point in 3D space at coordinates (x, y, z).

The line from the eye to the point (the red line) crosses the screen at a distance of x' pixels from the Z axis. It's simple geometry to work out the value of x' (should I mention similar triangles?). The value of x' is:
x'= (F / z) * x.

You can work out the Y value on the screen in exactly the same way. Just imagine the above picture being a view from the side instead of from the top. That gives you:
y' = (F / z) * y

I'll sum that up with a VB.Net function for finding the screen position of any 3D point:
Code:
```   Private Function ScreenCoordinatesFrom3D(F As Single, x As Single, y As Single, z As Single) As PointF
Dim s As Single = F / z
Return New PointF(x * s, y * s)
End Function```
F is the eye distance from the screen, and x, y and z are the coordinates of the point. The Z axis usually goes through the centre (of the Form, PictureBox etc.). So if your x and y are measured from the top left corner (as usual for GDI+), you must add half the width and height of the drawing area to centre the axis.

That's the end of the easy part of 3D perspective. The real problems arise when you decide to model an object or a scene in 3D. How do you work out the z values of all the points to be drawn?

It's easy enough to model a cube when it's centred on the z axis and its front is parallel to the screen. Rotating the cube around the Z axis is just a 2D problem, as mentioned. And you can solve the problem of rotating the cube around its own X or Y axis with fairly basic trigonometry. But to portray anything more, the calculations can get very messy and error-prone That's when people need concepts like vectors, matrics, quaternions and who knows what else...

BB

15. ## Re: GDIPLUS: how draw the point Z?

i'm sorry, but given the X,Y and Z(10,10,30), how can i draw an Ellipse using that 3D point?
Code:
`Graphics.DrawEllipse(Pens.Black,New Rectangle(10,10,10,10))`
but where to put the Z?
i'm just using the X and Y?

16. ## Re: GDIPLUS: how draw the point Z?

Hi Joaquim, I think you are asking two very different questions. First of all, this:

Originally Posted by joaquim
i'm sorry, but given the X,Y and Z(10,10,30), how can i draw an Ellipse using that 3D point?
Code:
`Graphics.DrawEllipse(Pens.Black,New Rectangle(10,10,10,10))`
Ok, so you have a point whose coordinates are (10, 10, 30) in 3D space. There are two ways to plot a 3D point to the screen: isometric projection and perspective projection. In perspective projection, things look smaller when they are further away, and in isometric projection they don't.

Isometric projection is what Tanner_H recommended, and maybe he is right to do so. The visible size doesn't change with distance, so you can plot your point at x, y without involving the z value. But you still have to remember that the Z axis goes through the middle of your drawing area, not the top-left corner. Suppose you are drawing on PictureBox1. In Isometric projection, you can draw your ellipse to mark the point (x, y, z) at:
Code:
```Dim xCentred As Integer = x + PictureBox1.ClientSize.Width\2
Dim yCentred As Integer = y + PictureBox1.ClientSize.Height\2
e.Graphics.FillEllipse(xCentred - 5, yCentred - 5, 10, 10)```
As you can see, the z position isn't involved.

Now suppose you want to use the more realistic-looking Perspective projection. In that case you need z because things look smaller and points get closer together when they are further away (higher z value). So to draw your point (x, y, z) in PictureBox1 with Perspective, you could use this code:
Code:
```Dim F As Integer = 500 'assumed focal length (= distance of eye from screen) in pixels
Dim s As Single = CSng(F / z)
Dim xCentred As Integer = x * s + PictureBox1.ClientSize.Width\2
Dim yCentred As Integer = y * s + PictureBox1.ClientSize.Height\2
e.Graphics.FillEllipse(xCentred - 5 * s, yCentred - 5 * s, 10 * s, 10 * s)```
This code places the point (x, y, z) correctly on the screen. It also makes the black circle smaller as it gets further away. As you can see, it takes more arithmetic but not much more.

And now for your second question:
Originally Posted by joaquim
but where to put the Z?
i'm just using the X and Y?
Put z wherever you like! OK, it depends on what you want to draw. To draw a cube in 3D, for example, you need to figure out where the corners are (the x, y, z coordinates) in 3D space. The cube is an example of a 3D model which is fairly easy to make.

I hope it's clear that Perspective projection of a 3D model isn't much harder than Isometric projection. The main work is making the 3D model, and that will be the same whatever type of projection you choose.

edit: But there are other reasons why Isometric projection has been popular for games ever since the 1980s. The main one is that it takes much less computer power to project an image to a 3D surface. Individual points (and graphics paths, which consist of points) aren't usually a problem, but it takes a lot of processing to transform a raster bitmap with say 250,000 pixels. Games which use perspective projection are generally made with DirectX, WPF etc. because they can take advantage of features like texture mapping which are available in modern computer graphics hardware. GDI+ wasn't designed to deal with that.

BB

17. ## Re: GDIPLUS: how draw the point Z?

I responded further to what I assume was your post on the xtremevbtalk.com forum. The code there is using Isometric project, not perspective.
Since Isometric drawing uses lines that are parallel, then textures can be rendered using parallelograms which DrawImage supports.

One thing that I didn't incorporate from the VB6 plgblt version is the mask bitmap to make the "windows" in the face of the "buildings" transparent.
The "windows" are a dark green color and you can add a line to the .Net version to make those "windows" transparent by modifying the image using the MakeTransparent method.
In the Load procedure, after the images are loaded into the array from the resources, add the line to make dark green transparent
Code:
```'...
Picture3(0) = My.Resources.TestTextures.Clone(New Rectangle(0, 0, 41, 53), Imaging.PixelFormat.DontCare)   'building face
Picture3(1) = My.Resources.TestTextures.Clone(New Rectangle(126, 1, 41, 41), Imaging.PixelFormat.DontCare) 'gray face
Picture3(2) = My.Resources.TestTextures.Clone(New Rectangle(42, 0, 41, 53), Imaging.PixelFormat.DontCare)  'stone face
Picture3(0).MakeTransparent(Color.FromArgb(0, 128, 0))  'make dark green areas of this image transparent.
'...```
I noticed after adding the information above about using MakeTransparent, that this code is also using another feature that may be unfamiliar to a number of users.
It is using a BufferedGraphics object to handle the drawing and using its render method to update the screen area of Panel1.
I believe this updates the screen faster than using the standard paint event, but it also gives us some extra flexibility about when we update the drawing and from where. We could update the drawing from a background thread and render it to the screen directly from that background thread, which is not something you could normally do if drawing to the panel control directly. Access to the panel control would have to be done on the GUI thread. Technically, we are using the BufferedGraphics object to update the screen area of the control, not the control itself, so we can do that from any thread.

If this was a game and I was updating the screen continually I would not have any code in the Panel1.Paint event because it would be unnecessary. In this example's case, I'm updating the image on demand, in response to active keyboard input (i.e. the timer only calls the drawing code when at least one key is down, otherwise it skips doing any drawing). Since it isn't drawing continuously, Windows might "damage" the image on the screen somehow, and will cause a Paint event to fix it. So, in the paint event we will render the current BufferedGraphics maintained image to restore the image, but that is guarded by a mutex so that if we were in the middle of updating the image, the paint event would wait until the image was updated before drawing.

Actually that is unnecessary in this example because the drawing update is not being done in a separate thread, so the paint event and the drawing (which is called from the tick event) can't happen at the same time. I notice that System.Threading was imported at the top of the file but isn't taken advantage of in this code. I probably have other code that did use another thread to do the drawing updates, but here chose to make it a little simpler and just have a GUI timer do the updates. Therefore, the Mutex is unnecessary. I also noticed that at least one comment ended up migrating from the line it should be on, to a line that doesn't make any sense for it to be there.
Code:
```'... The End Sub for Form1_Keyup Sub has this comment
End Sub  'to substitute for ScaleTop property of vb6 picturebox

'... Which should be on this line up in the declarations area
Dim ScaleTop As Integer = -300
'...```
I guess I'll attach the VB.Net 2010 version of the code to this post as well for those people who don't want to follow the link to the other forum.

You might also want to check out post #13 from this thread, whose example is based on DFPCNC's code, I believe. It is just rotating a cloud of dots a couple of ways, again without perspective.

p.s. One important thing that the code in post #13 isn't doing is ordering the dots by their z value and drawing the dots from back to front. Because of that, a lot of the 3D information is "lost" because dots that should be hidden behind dots that are in front of them end up being drawn on top of them so appear closer to the viewer rather than where their Z value indicates.
I do see on my disk that I did continue to play with the example some after that post so added Z-order processing to provide a truer sense of a 3d cloud of dots. The code is rough, with a lot of commented out code in it, and the body axis side of the example apparently doesn't do anything any longer, but if you would like to see the later version, I can pack it up and attach it "as is" in another post.

18. ## Re: GDIPLUS: how draw the point Z?

boops boops: thank you so much, now i get the point. now i can use the eye. but imagine that i use another ellipse with a distance 10 between them?
how can i calculate their distance. is just use the X and Y for the new ellipse?

19. ## Re: GDIPLUS: how draw the point Z?

Originally Posted by joaquim
boops boops: thank you so much, now i get the point. now i can use the eye. but imagine that i use another ellipse with a distance 10 between them?
how can i calculate their distance. is just use the X and Y for the new ellipse?
I don't know what you mean by "a distance of 10 between them". Do you mean distance in 3D space, distance along one of the axes (X, Y or Z) or distance on the screen? Whatever you mean, the code I posted in #16 should give you the right answer. But I'm not sure that solves your problem.

So far I have been talking about "conventional" 3D coordinates, with the Z axis at right angles to the middle of the drawing area on the screen. The image you posted in #13 shows the X, Y and Z axes that are rotated in space in relation to the conventional coordinates. In other words, it's a 3D model that has been rotated. I don't think it's a good idea for you to start from there, because the mathematics of a rotated 3D coordinate system gets rather complicated. Instead, I suggest you start by considering the rotation of a square (as I suggested in your other thread) and then of a cube. You can do quite a lot with that. Please tell me if you have problems understanding my question there, because that's about the 3D model.

BB

20. ## Re: GDIPLUS: how draw the point Z?

thanks to you i anderstand better the 3D. but now i can't test the code. i haded 1 accident on work and some bronken bones. so now i must think on me
i will not close these topic for i learn more: like create a world and move arrow it, is what i'm trying to learn.
thanks for all

21. ## Re: GDIPLUS: how draw the point Z?

Sorry to hear about your accident Joaquim. Take it easy and get better soon!

If you feel up to some reading (in English) you might like to look at this 3D tutorial on the Khan Academy website. The explanation is very good.

There are some good interactive examples too, so I hope your mouse hand isn't affected. Unfortunately the examples are coded in JScript, but I'm sure it will be possible to port them to VB.Net.

BB

22. ## Re: GDIPLUS: how draw the point Z?

thank you so much for all. and thanks to all

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•

Featured