How can I zoom...
Blitz3D Forums/Blitz3D Beginners Area/How can I zoom...
| ||
I want to create a top down view of a machine where the user can import a 2D CAD DXF file of a sheet metal part and then be able to move the machine and part and get various pieces of data. I have alot of it working but have realized that I need some zooming capabilities because the machine is very large and sometimes the parts are very small and I need to be able to zoom in on the small parts so that I can see them better. How can I zoom? Here is a sample of my code so far that does not have any zooming capabilities. You use the arrow keys to move the machine parts around. Thanks for any help, David Graphics3D 1280, 960 SetBuffer BackBuffer() AppTitle "Autoform Gage Simulation" CenterX = GraphicsWidth()/2 CenterY = GraphicsHeight()/2 MyScale = 10 LBoxX# = CenterX - 10 * MyScale LBoxY# = CenterY - 100 RBoxX# = CenterX + 9 * MyScale RBoxY# = CenterY - 100 FingerToMove$ = "BOTH" XMovementAmount = 1 YMovementAmount = 1 ClsColor 255,255,255 Cls While Not KeyDown(1) Color 0,0,0 If KeyDown(203) Then ;move left If FingerToMove = "LEFT ONLY" Then LBoxX = LBoxX - XMovementAmount End If If FingerToMove = "RIGHT ONLY" Then RBoxX = RBoxX - XMovementAmount End If If FingerToMove = "BOTH" Then LBoxX = LBoxX - XMovementAmount RBoxX = RBoxX - XMovementAmount End If If FingerToMove = "PART" Then PartX# = PartX# - XMovementAmount End If End If If KeyDown(205) Then ;move right If FingerToMove = "LEFT ONLY" Then LBoxX = LBoxX + XMovementAmount End If If FingerToMove = "RIGHT ONLY" Then RBoxX = RBoxX + XMovementAmount End If If FingerToMove = "BOTH" Then LBoxX = LBoxX + XMovementAmount RBoxX = RBoxX + XMovementAmount End If If FingerToMove = "PART" Then PartX# = PartX# + XMovementAmount End If End If If KeyDown(200) Then ;move up If FingerToMove = "LEFT ONLY" Then LBoxY = LBoxY - YMovementAmount End If If FingerToMove = "RIGHT ONLY" Then RBoxY = RBoxY - YMovementAmount End If If FingerToMove = "BOTH" Then LBoxY = LBoxY - YMovementAmount RBoxY = RBoxY - YMovementAmount End If If FingerToMove = "PART" Then PartY# = PartY# - YMovementAmount End If End If If KeyDown(208) Then ;move down If FingerToMove = "LEFT ONLY" Then LBoxY = LBoxY + YMovementAmount End If If FingerToMove = "RIGHT ONLY" Then RBoxY = RBoxY + YMovementAmount End If If FingerToMove = "BOTH" Then LBoxY = LBoxY + YMovementAmount RBoxY = RBoxY + YMovementAmount End If If FingerToMove = "PART" Then PartY# = PartY# + YMovementAmount End If End If If KeyHit(29) Then ;toggle which finger(s) to move Select FingerToMove Case "PART" FingerToMove = "LEFT ONLY" Case "LEFT ONLY" FingerToMove = "RIGHT ONLY" Case "RIGHT ONLY" FingerToMove = "BOTH" Case "BOTH" FingerToMove = "PART" End Select End If ;draw left gauge now... Rect(LBoxX, LBoxY, 1 * MyScale, 1.5 * MyScale,0) Line(LBoxX + 1 * MyScale, LBoxY + .5 * MyScale, LBoxX + 2 * MyScale, LBoxY + .5 * MyScale) Line(LBoxX + 2 * MyScale, LBoxY + .5 * MyScale, LBoxX + 2 * MyScale, LBoxY + 2.5 * MyScale) Line(LBoxX + 2 * MyScale, LBoxY + 2.5 * MyScale, LBoxX + 1.75 * MyScale, LBoxY + 2.5 * MyScale) Line(LBoxX + 1.75 * MyScale, LBoxY + 2.5 * MyScale, LBoxX + 1.75 * MyScale, LBoxY + 2.375 * MyScale) Line(LBoxX + 1.75 * MyScale, LBoxY + 2.375 * MyScale, LBoxX, LBoxY + 1.5 * MyScale) ;Line(CenterX - 60 * MyScale, LBoxY - 15, LBoxX + .5 * MyScale, LBoxY - 15) ;Text CenterX - 63 * MyScale + ((LBoxX + .5 * MyScale) - (CenterX - 60 * MyScale))/2, LBoxY - 15, Str$(LBoxX / MyScale - 63.5) ;draw right gauge now... Rect(RBoxX, RBoxY, 1 * MyScale, 1.5 * MyScale,0) Line(RBoxX, RBoxY + .5 * MyScale, RBoxX - 1 * MyScale, RBoxY + .5 * MyScale) Line(RBoxX - 1 * MyScale, RBoxY + .5 * MyScale, RBoxX - 1 * MyScale, RBoxY + 2.5 * MyScale) Line(RBoxX - 1 * MyScale, RBoxY + 2.5 * MyScale, RBoxX - .75 * MyScale, RBoxY +2.5 * MyScale) Line(RBoxX - .75 * MyScale, RBoxY + 2.5 * MyScale, RBoxX - .75 * MyScale, RBoxY + 2.375 * MyScale) Line(RBoxX - .75 * MyScale, RBoxY + 2.375 * MyScale, RBoxX + 1 * MyScale, RBoxY + 1.5 * MyScale) ;Line(CenterX + 60 * MyScale, RBoxY - 15, RBoxX + .5 * MyScale, RBoxY - 15) ;Text CenterX + 63 * MyScale + ((RBoxX - .5 * MyScale) - (CenterX + 60 * MyScale))/2, RBoxY - 15, Str$(RBoxX / MyScale - 63.5) ;draw bed centerline Line(CenterX, CenterY, CenterX, CenterY + 2.5 * MyScale) ;draw bed Line(CenterX, CenterY, CenterX + 60 * MyScale, CenterY) Line(CenterX, CenterY, CenterX - 60 * MyScale, CenterY) Line(CenterX, CenterY + 2.5 * MyScale, CenterX + 60 * MyScale, CenterY + 2.5 * MyScale) Line(CenterX, CenterY + 2.5 * MyScale, CenterX - 60 * MyScale, CenterY + 2.5 * MyScale) ;draw tooling centerline now... Color 255,0,0 Line(CenterX - 60 * MyScale, CenterY + 1.25 * MyScale, CenterX + 60 * MyScale, CenterY + 1.25 * MyScale) ;draw maximum X axis location now Line(CenterX - 60 * MyScale, CenterY - 22.75 * MyScale, CenterX + 60 * MyScale, CenterY - 22.75 * MyScale) Color 0,0,0 If ReadPixel(LBoxX,LBoxY + 2.5 * MyScale) = -65536 Then Collision = 1 End If If ReadPixel(RBoxX,RBoxY + 2.5 * MyScale) = -65536 Then Collision = 2 End If Select Collision Case 0 ;print the gage locations to the screen Text 10, 10, "ZLeft = " + Str$(LBoxX / MyScale - 63.5) Text 160, 10, "ZRight = " + Str$(RBoxX / MyScale - 63.5) Text 10, 25, "XLeft = " + Str$((LBoxY / MyScale - 46.75)*-1) Text 160, 25,"XRight = " + Str$((RBoxY / MyScale - 46.75)*-1) Text 10, 40, "Finger to move LFT CTRL KEY = " + FingerToMove Text 10, 55, "OK" Case 1 While Not KeyDown(46) ;print the gage locations to the screen Text 10, 10, "ZLeft = " + Str$(LBoxX / MyScale - 63.5) Text 160, 10, "ZRight = " + Str$(RBoxX / MyScale - 63.5) If (LBoxY / MyScale - 46.75)*-1 > 1.25 Then Text 10, 25, "XLeft = " + "24.000" Else Text 10, 25, "XLeft = " + "0.000" End If Text 160, 25,"XRight = " + Str$((RBoxY / MyScale - 46.75) * -1) Text 10, 40, "Finger to move LFT CTRL KEY = " + FingerToMove Text 10, 55, "Left Gage Collision Detected !!! Press C and a direction button to continue." Flip Wend Collision = 0 Case 2 While Not KeyDown(46) ;print the gage locations to the screen Text 10, 10, "ZLeft = " + Str$(LBoxX / MyScale - 63.5) Text 160, 10, "ZRight = " + Str$(RBoxX / MyScale - 63.5) Text 10, 25, "XLeft = " + Str$((LBoxY / MyScale - 46.75)*-1) If (RBoxY / MyScale - 46.75)*-1 > 1.25 Then Text 160, 25, "XRight = " + "24.000" Else Text 160, 25, "XRight = " + "0.000" End If Text 10, 40, "Finger to move LFT CTRL KEY = " + FingerToMove Text 10, 55, "Right Gage Collision !!! Press C and a direction button to continue." Flip Wend Collision = 0 End Select Flip Cls Wend End |
| ||
- edit - Post deleted. Ah, nevermind, ive just seen its all in 2d. sorry. (im at work & didnt read it carefully enough :P) -edit 2- Heres an idea though: Let 3D help : You should be able to recreate it in 3D space (just dont use the Z axis) using a system of dynamic invisible pivots (see createpivot & freeentity) that are deleted/created when they and/or their linked counterparts are on/off screen respectively, using a custom data type (or array) that stores the coords of the 2 pivots that make it up (or use 4 for rectangles). Then use the line command to join up the screen coords of those pivots (see cameraproject command). Lastly use b3d's orthomode (cameraprojmode cam,2) with the camerazoom command. Redrawing the lines after the zoom. Worth a try and would save you a lot of maths design. You could even create a way of editing the points easily too if you wanted to do that. Im sure someone will have a nice 2d solution for you if you hold out though :) |
| ||
Thanks for the idea but I am a beginner and will hold out to see if someone might offer a simpler solution as I did not understand all of your ideas. I have thought about 3D but I could not figure out how to import my 2D DXF CAD file into a 3D environment. The 2D DXF CAD file has information required for drawing lines, circles and partial circles (arcs). I could not figure out how take those 2D elements and draw them into a 3D part. If I could figure that out, 3D would be a much better solution for me because it would provide a way for me to flip, rotate and move the part around on the screen much easier. Still looking for a simple zoom solution, if there is such a thing. Thanks, David |
| ||
Why not just do all your 2d drawing, copy the screen to a texture and then display the texture on a quad? |
| ||
Gabriel, I am so new that I don't even know what a quad is. It might work but I would need to learn about what a quad is. I need to be able to interactively move my machine parts and the flat sheet metal part around on the screen and be able to zoom in and out to see better. As I move the machine parts around on the screen, I need the X-Left, X-Right, Z-Left and Z-Right locations to update appropriately and accurately. The X-Left, Z-Left etc. are parts of a machine that are used for positioning flat sheet metal parts so that they can be bent into a 3D shape. Does this still sound like your idea might work? Thanks, David |
| ||
A quad is just a completely flat 3d rectangular object. It's 3d in theory because it has a three dimensional position, but in practice, it's just a 2D item you can scale. You can interactively do whatever you want to do because you're still going to be drawing it every frame, just as you are in 2d. The only difference is that - because it's a 3d element - you'll be able to scale it any size you want, which equates to zooming in or out. |
| ||
You can also zoom into a quad with CameraZoom |
| ||
I have limited experience with CAD, i did it for a few years. From what i can remember, The CAD zoom is very much the same as a vector drawing program zoom. There should be no blocky lines or graphics, no matter how many times you can zoom in. Why not set a size for your screen. Say 5000 x 5000 units. Now, you will have a screen_start_x variable, and a screen_start_y variable, and obviously a screenwidth and screenheight. Now, instead of saying a line stretches from (0,0) to (1280,0) across the full length of your screen, based on your choosen resolution, you would say the lines co-ordinates are (0,0) to (5000,0). Now, when it comes to drawing you will need to translate these unit co-ords to actual onscreen co-ords. For example: Unit co-ords of a line (0,0) (5000,0) Now since 5000 is your maximum screen unit width, and 1280 is your maximum screen pixel width, you will need to clip the line at each end of the screen, and based on where the viewport is. Blitz will clip the graphics for you. Graphics 800,600 SetBuffer BackBuffer() While Not KeyHit(1) Cls Oval -1000,0,1050,300 Flip Wend That draws an oval, starting from -1000, and stretching 1050 across and 300 down. Only 50 pixels across are showing. The only problem is slight inaccuracies you'd get, only a pixel out at any one time. The fact a unit may lie between two pixels at a zoomed out factor. |
| ||
Guys... Thanks for all of the information. I am at work now but I will try some of these ideas out when I get home and see if I can get something to work. Thanks again, David |
| ||
Not sure about the format of DXF files but if it is basically a list of points and lines then it should be easy to implement a 2d zoom. For example. NOTE: this is just typed straight into the thread so won't work off the bat. I'm also assuming that your just reading the points / lines from data statements which will not be the case. I'm also pretty sure that you can re-define arrays like this but I may be wrong. global Lines global Points ;array to store point x & y coords dim PointX#(0) dim PointY#(0) ;array to store zoomed x & y coords dim PointZX#(0) dim PointZY#(0) ;array to store line start and end point indices. dim LineS(0) dim LineE(0) INIT() DRAW() mousewait end ;===================================== ;===================================== ;===================================== ;read all the points / lines Function INIT() Restore MyData read Points dim PointX#( Points - 1 ) dim PointY#( Points - 1 ) dim PointZX#( Points - 1 ) dim PointZY#( Points - 1 ) read Lines dim LineS( Lines - 1 ) dim LineE( Lines - 1 ) ;read all point x & y coords for p = 0 to Points - 1 read PointX( p ) read PointY( p ) next ;read all start and end point indexes for l = 0 to Lines - 1 read LineS( l ) read LineE( l ) next end function ;===================================== ;===================================== ;===================================== function DRAW( Ox# , Oy# , Zoom# = 1.0 ) ;get new point coords after applying zoom on origin Ox, Oy for p = 0 to Points - 1 PointZX( p ) = ( PointX( p ) - Ox ) * Zoom PointZY( p ) = ( PointY( p ) - Oy ) * Zoom next ;draw the lines for the new points for l = 0 to Lines - 1 Line PointZX( LineS( l ) ) , PointZY( LineS( l ) ) , PointZX( LineF( l ) ) , PointZY( LineF( l ) ) next end function ;===================================== ;===================================== ;===================================== |
| ||
Ok man, i've completed my little code. Can't nail the little zoom problem i'm having though... Floating point inaccuracy somewhere i thinks. Anyway: Using something like stevie has posted to make the lines. I've only hardcoded in an oval to demonstrate real time zooming and movement. Arrow keys to move. PageUP and PageDOWN to zoom in and out. The comments for the zooming code is inaccurate, as i changed it :oS |
| ||
Ross C, That is an impressive piece of code. I will give it a try and see if it will work for me. Thanks for your time and help with this. David |
| ||
All you really need to do plot your points or draw your lines, using the unit scale and not the pixel scale. For instance if your line goes from 100 to 500, and the number of units on the screen is 1600,1200, the line would go from: max_unit_x# = 1600 ; the number of units across your screen. max_pixels_x# = 800 ; the number of pixels wide your screen is ratio = max_pixels / max_unit_x Multiply ever co-ord for your line/oval/plot, by the ratio figure. The drawviewport code will translate your unit co-ords back to pixel co-ords onscreen when drawing. And your very welcome :o) |
| ||
"hollifd" your User ID is 2195. Did you buy Blitz a few years back then stopped using it? |
| ||
puki, I bought it from someone on Ebay (maybe a year or two ago?) and have not used it (mostly because I don't know how). I am fascinated at some of the things I have seen users create and am just now trying to learn more about it. I work as a manufacturing engineer and am trying to create a machine simulator with some CAD type functionality using Blitz and am struggling a bit. I think it would be easier if I could do some of this in 3D but have not been able to figure out how to create lines, circles and arcs in 3D. I need to work with 2D DXF CAD files and write some code that will read through the DXF file to get the information for each line, circle and arc. I think I have figured out the DXF file format but have not figured out how to draw the lines, circles and arcs to create a 3D part. Here is what I THINK I need to do... I think I need to read the DXF file and get the information for all of the lines, circles and arcs then draw them onto the screen. Then I think I need to WELD them all together so that they will all move, flip and rotate together? At some point, I will probably ask some more questions on this board to see if anyone can help. David |
| ||
Tbh, i think 2d might be easier for you, especially if your new. You don't need to worry about surfaces, cameras, vertex co-ords, creating quads. Althought zooming is far easier, what i have given you above, is more than enough for doing the zooming stuff. With 2d, you just need to draw your arcs and lines everyframe and not worry about clipping issues, drawing too many quads etc. |
| ||
Ross C, Anonther reason that I think 3D might be easier is because I also need the ability to flip my part over and rotate it. I guess through code I could rotate all of the X and Y coordinates of each line and arc around a center point in order to rotate the part. As far as flipping the part, I will need to see what needs to happen to each of the X and Y coordinates in order to create the flip. I have thought about just drawing the part on the screen and then create an image from the drawing, then use some of the built in commands for rotating and flipping the image. I am not sure what will happen when I try to zoom in and out with this method. My guess is that everything except the image will zoom in and out. I want to experiment with one of the ideas above about drawing to a texture and then placing the texture onto a cube (quad?) just to see what that might do for me. I want to also look at our CAD software and see if it can export a file format that is able to be imported into Blitz3D. That seems like it would make things alot simpler too. Anyway...I am having fun (?) with this and learning a few tricks too. David |
| ||
Flipping would be very easy, and so would rotating, if it's just rotating points that make up shapes. Make a centre point, then use SIN and COS to find your new points. If you zoom into an image, it will just appear as it does i'm afraid. Zooming into a bitmap will produce a blocky effect, but there is no reason why you need to change your part into an image. If you want to learn more about programming, try the 2d way first. When you go into 3d, trying to draw an arc, with a series of joined up quads is possible, BUT, when you zoom in, which will be a breeze, your lines will get thicker, unless your dynamically alter all the quads. So, either way, you will have problems to overcome, that the other option won't have. Since you have a working zoom code, that seems to be most of the troubles of the 2d finished. A note about zooming into the texture on a cube as you suggested. If you drew some lines in paint, them zoomed into them, you'd get a blocky version of what you have drawn. Same applies in 3d, unless you vectorise the 3d drawing, in which case, drawing to a texture would be kind of out the window :o) Try drawing a small CAD drawing saving it as a square texture 2x2 or 4x4 or 8x8 or 16x16... etc, must be multiple of 2. Texture a cube with it, and place the camera at different distances away, to quickly see the effect of what will happen :o) Glad your having fun with this too :o) Good luck! |
| ||
Ross C, I tried drawing to a texture and it does not seem all that bad. The zooming is very easy but I can see what you mean about the lines not remaining crystal clear. I don't think it will be a problem for what I am trying to do. One problem that I do not understand... If I want to use this method, how do I size the texture to fit exactly onto my cube. It looks like the texture is being stretched to fit onto the cube and the graphics are being distorted. Is there a way that I can draw to a texture size and when I apply the texture to the cube it will be placed onto the cube without and distortion of my lines and arcs. Hopefully you can uderstand what I am trying to say. Here is the code that I used... Use the arrow keys to move the camera Use Z to zoom in User V to zoom out Graphics3D 640,480 SetBuffer BackBuffer() camera=CreateCamera() PositionEntity camera, 0,0,-250 light=CreateLight() RotateEntity light,90,0,0 cube=CreateCube() PositionEntity cube,0,0,0 ScaleEntity cube, 120,120,1 ; Create texture of size 256x256 tex=CreateTexture( 640,480 ) ; Set buffer - texture buffer SetBuffer TextureBuffer( tex ) ; Clear texture buffer with background white color ClsColor 255,255,255 Cls ; Draw some sample lines / circles on the screen Color 0,0,0 Rect(10, 10, 630, 470, 0) Oval(270, 190, 100, 100, 0) ; Texture cube with texture EntityTexture cube,tex ; Set buffer - backbuffer SetBuffer BackBuffer() While Not KeyDown( 1 ) If KeyDown( 208 ) Then MoveEntity camera, 0,-1,0 End If If KeyDown( 200 ) Then MoveEntity camera, 0,1,0 End If If KeyDown( 203 ) Then MoveEntity camera, -1,0,0 End If If KeyDown( 205 ) Then MoveEntity camera, 1,0,0 End If If KeyDown( 44 ) Then MoveEntity camera, 0,0,1 End If If KeyDown( 47 ) Then MoveEntity camera, 0,0,-1 End If RenderWorld Flip Wend End |
| ||
tex=CreateTexture( 640,480 ) This will create a texture of 1024 x 512 on most cards as they'll round to the nearest power of 2. Obviously this is non-square so will look distorted on a cube. If you create a texture of 1024 x 1024 it should look fine. Alteratively you can use scaletexture to adjust the uv's. Stevie |
| ||
Thanks Stevie G. When I create the texture at 1024 x 1024, my picture does not look distorted any more. Is there a way to take my simple rectangle and hole drawing and create a 3D model? The model can be flat or have thickness and should be wireframe so that I can see through it. Ultimately, I want to read a 2D DXF CAD file draw lines, circles and partial circles. I have seen some code here about drawing 3D lines and I am wondering if I might be able to utilize that to draw a part in 3D. For the circles, maybe I could use very short line segments rotated around an axis to simulate the look of a circle. Thanks, David David |