Qbasicnews.com

Full Version: cool 3d thing (edit: now available in screensaver form!)
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
its not too complicated, so dont get your hopes too high, but i like it. Big Grin
Code:
DECLARE SUB rotpt (x1!, y1!, z1!, rotx!, roty!, rotz!, nx!, ny!, nz!)
DECLARE FUNCTION dstc(x1!,y1!,x2!,y2!,d!) AS BYTE
CONST pi = 3.14159 / 180
DIM AS SINGLE x,y,z,thetax,thetay,thetaz, c,ox,oy,bx,by,bz,cx,cy,tm
DIM AS INTEGER sc(639*479+1),mousex,mousey,garbage
RANDOMIZE TIMER
SCREENRES 640,480,32,2
SCREENSET 1,0
ox = 320
oy = 240
cx = -5
cy = -8
tm = TIMER + .03
DO
    FOR thetax = 0 TO 180 STEP 36
        FOR thetay = 0 TO 360 STEP 6
            rotpt (0,0,125,thetay,thetax+90+thetaz,thetaz+90,x,z,y)
            c = (y+128) SHL 16
            LINE (ox-x-1,oy-z-1)-(ox-x+1,oy-z+1),c, bf
            rotpt (0,0,225,-thetay,-thetax+90-thetaz,-thetaz+90,bx,bz,by)
            c = ((y*.55)+128)
            LINE (319-bx,239-bz)-(321-bx,241-bz),c, bf
        NEXT
    NEXT
    SCREENCOPY 1,0
    GET (0,0)-(638,478),sc
    CLS
    DO:LOOP UNTIL TIMER >= tm
    tm = TIMER + .03
    PUT(1,1),sc,alpha,225
    LINE(0,0)-(639,0),0
    LINE(0,0)-(0,479),0
    thetaz +=2
    ox += cx
    IF ox < 125 OR ox > 514 THEN cx = -cx    
    oy += cy
    IF oy < 125 OR oy > 354 THEN cy = -cy
LOOP UNTIL MULTIKEY(1)
END
SUB rotpt (x1!, y1!, z1!, rotx!, roty!, rotz!, nx!, ny!, nz!)
    DIM AS SINGLE rx,ry,rz
    rx = rotx!
    ry = roty!
    rz = rotz!
    'xrot
    nx1! = x1!
    ny1! = z1! * SIN(pi * rx) + y1! * COS(pi * rx)
    nz1! = z1! * COS(pi * rx) - y1! * SIN(pi * rx)
   'yrot
    nx2! = nx1! * COS(pi * ry) - nz1! * SIN(pi * ry)
    ny2! = ny1!
    nz2! = nx1! * SIN(pi * ry) + nz1! * COS(pi * ry)
    'zrot
    nx! = nx2! * COS(pi * rz) - ny2! * SIN(pi * rz)
    ny! = nx2! * SIN(pi * rz) + ny2! * COS(pi * rz)
    nz! = nz2!    
END SUB

FUNCTION dstc(x1!,y1!,x2!,y2!,d!) AS BYTE
    IF SQR((x1!-x2!)*(x1!-x2!)+(y1!-y2!)*(y1!-y2!)) > d! THEN RETURN -1 ELSE RETURN 0
END FUNCTION
ok, following the advice of rattrap, i made it into a screensaver.
Download screensaver
Here is the code for those who are interested:

edit: changed the code to make the empty settings thing look more windows-y, lol

Code:
IF LEFT$( COMMAND$, 2 ) = "/c" THEN 'settings
    DIM AS INTEGER mx,my,mb, txt(340*40)
    SCREENRES 400,300,32,2,0
    SCREENSET 1,0
    WINDOWTITLE "Sphereoyds© Settings"
    PAINT (0,0), RGB(255,0,255)
    COLOR RGB(0,0,0), RGB(255,0,255)
    PRINT "Sorry, no settings are currently available."
    PRINT
    PRINT "           Screensaver by Deleter,"
    PRINT
    PRINT "            'Sphereoyds' (c) 2005"
    GET (0,0)-(339,39),txt
    CLS
    PAINT(0,0), RGB(212,208,200)
    PUT (29,129),txt,trans
    SCREENCOPY 1,0
    SLEEP
    END
END IF
IF LEFT$( COMMAND$, 2 ) = "/p" THEN END
DECLARE SUB rotpt (x1!, y1!, z1!, rotx!, roty!, rotz!, nx!, ny!, nz!)
DECLARE FUNCTION keypressed()
CONST pi = 3.14159 / 180
DIM AS SINGLE x,y,z,thetax,thetay,thetaz, c,ox,oy,bx,by,bz,cx,cy,tm
DIM AS INTEGER sc(639*479+1),mousex,mousey,garbage
RANDOMIZE TIMER
SCREENRES 640,480,32,2,1
SCREENSET 1,0
SETMOUSE 320,240,0
ox = 320
oy = 240
cx = -2.5
cy = -4
tm = TIMER + .03

DO
    FOR thetax = 0 TO 180 STEP 36
        FOR thetay = 0 TO 360 STEP 6
            rotpt (0,0,125,thetay,thetax+90+thetaz,thetaz+90,x,z,y)
            c = (y+128) SHL 16
            LINE (ox-x-1,oy-z-1)-(ox-x+1,oy-z+1),c, bf
            rotpt (0,0,225,-thetay,-thetax+90-thetaz,-thetaz+90,bx,bz,by)
            c = ((y*.55)+128)
            LINE (319-bx,239-bz)-(321-bx,241-bz),c, bf
        NEXT
        SLEEP 1
    NEXT
    
    SCREENCOPY 1,0
    GET (0,0)-(638,478),sc
    CLS
    DO:LOOP UNTIL TIMER >= tm
    tm = TIMER + .03
    PUT(1,1),sc,alpha,225
    LINE(0,0)-(639,0),0
    LINE(0,0)-(0,479),0
    thetaz +=2
    ox += cx
    IF ox < 125 OR ox > 514 THEN cx = -cx    
    oy += cy
    IF oy < 125 OR oy > 354 THEN cy = -cy
LOOP UNTIL keypressed
END
SUB rotpt (x1!, y1!, z1!, rotx!, roty!, rotz!, nx!, ny!, nz!)
    DIM AS SINGLE rx,ry,rz
    rx = rotx!
    ry = roty!
    rz = rotz!
    'xrot
    nx1! = x1!
    ny1! = z1! * SIN(pi * rx) + y1! * COS(pi * rx)
    nz1! = z1! * COS(pi * rx) - y1! * SIN(pi * rx)
   'yrot
    nx2! = nx1! * COS(pi * ry) - nz1! * SIN(pi * ry)
    ny2! = ny1!
    nz2! = nx1! * SIN(pi * ry) + nz1! * COS(pi * ry)
    'zrot
    nx! = nx2! * COS(pi * rz) - ny2! * SIN(pi * rz)
    ny! = nx2! * SIN(pi * rz) + ny2! * COS(pi * rz)
    nz! = nz2!    
END SUB

FUNCTION keypressed()
    DIM AS INTEGER temp,tx,ty
    FOR temp = 0 TO 127
        IF MULTIKEY(temp) THEN RETURN -1
    NEXT
    GETMOUSE tx,ty,,temp
    IF tx <> 320 OR ty <> 240 OR temp <> 0 THEN RETURN -1
    RETURN 0
END FUNCTION
good job deleter. Keep it up. I could definately use that as a screensaver. 8) and then if someone asks how it was made, then ill introduce them to freebasic. :lol:
how was it made? i'm not kidding.
oh let's start with rotpt

btw, where the hell do you people learn any of this stuff? did i miss something? goddamn, where the hell is a good, thorough, tutorial to help me?! Damn.

thank you that is all.

oh, and that look pretty cool 8)

edit: i used the wrong word. go figure
well the rotpt sub i got from syn9 and edited it a bit. i asked him and he wasnt quite sure how/why it worked.....

Its the magical formula!


lol, jk

As soon as I figure it out, I'll tell you how it works, lol. But i can tell you it deals with a lot of trig. I get everything up until z rotation, that just blows me out of the water...
all 3d stuff breaks down to simple Vector math that's it nothing more.
and 3d vectors are simple 2d vectors but just the Z component on the vector has a relation ship X or Y components of the vector doesn't matter really which.

Rel did a really good tutorial on this i think it's still up on the main QBN front page.
ooooooooh, rotpt is a sub! damn. well ok. n/m :oops:
:lol: Yeah,

Code:
SUB rotpt (x1!, y1!, z1!, rotx!, roty!, rotz!, nx!, ny!, nz!)
    DIM AS SINGLE rx,ry,rz
    rx = rotx!
    ry = roty!
    rz = rotz!
    'xrot
    nx1! = x1!
    ny1! = z1! * SIN(pi * rx) + y1! * COS(pi * rx)
    nz1! = z1! * COS(pi * rx) - y1! * SIN(pi * rx)
   'yrot
    nx2! = nx1! * COS(pi * ry) - nz1! * SIN(pi * ry)
    ny2! = ny1!
    nz2! = nx1! * SIN(pi * ry) + nz1! * COS(pi * ry)
    'zrot
    nx! = nx2! * COS(pi * rz) - ny2! * SIN(pi * rz)
    ny! = nx2! * SIN(pi * rz) + ny2! * COS(pi * rz)
    nz! = nz2!  
END SUB

Tongue Read up on Relsolf's 3D tuts for QB if you want a basic understanding (pun intended) :wink:

Edit: Ah, yeah, I found a replacement for my saver for awhile.. 8) ..That just looks too cool.. :lol:
hah! i didnt say i didnt know how it worked... i said i didnt know why all my returned X points were negative! >D

heres a tutorial i wrote on why it works... >)


for rotation on a 2d plane, take a normal x/y axis and place a point on the x axis somewhere

a simple exercise would be to rotate that point by 90 degrees up to the y axis

so point [10,0] becomes [0,10]

well, cos(0degrees) = 1 and sin(90 degrees) = 1

so if you want the x value to be at 10 on the x axis at 0 degrees then multiply the x value by cos(angle), this will give you the rotated x coordinate

now, since you want that initial point on the x axis to be put up to the top of the y axis, you'll multiply the x point times sin(90) so that at 90 degrees the rotated y value will be 10 units high

so far you have

rotatedx = x * cos(angle)
rotatedy = x * sin(angle)

so that if you put in the coordinate [10,0] it will be on the x plane at value 10 at 0 degrees and it will be on the y plane at 90 degrees...

now, say you want the point [10,2] the be rotated 90 degrees, well, at 0 degrees y ou want the point to be 2 units above the x axis

so you add to your rotatedy value y * cos(0) because at 0 degrees cos(0) = 1 and sin(0) = 0... so that your x*sin[0] = 0 and y*cos[0] = 2, now your rotatedy formula will acurately rotate this point that is not exactly on the x axis

next is to fix the rotatedx formula so that at 90 degrees the original [10,2] is rotated to [-2,10] in order to do this your rotated x value needs to end up at -2 at 90 degrees, well, cos[90] = 0 so you need to use sin[90] and multiply it by the negative of the original y value

so you end up with

rotatedx = x * cos[angle] - y * sin[angle]
rotatedy = x * sin[angle] + y * cos[angle]

this will allow rotation on one plane, in 3d you have 3 planes, so the outputed rotatedx/y from this formula will be applied to the next plane, and so on to have a final rotated coordinate in 3d

to rotate onthe x axis, you'll be rotating on a plane that only uses z and y values
on the y axis, it'll be x and z values etc...


simplified it would look like this

rx1 = basex
ry1 = basez * sin(xangle) + basey * cos(xangle)
rz1 = basez * cos(xangle) - basey * sin(xangle)

rx2 = rx1 * cos(yangle) - rz1 * sin(yangle)
ry2 = ry1
rz2 = rx1 * sin(yangle) + rz1 * cos(yangle)

rx3 = rx2 * cos(zangle) - ry2 * sin(zangle)
ry3 = rx2 * sin(zangle) + ry2 * cos(zangle)
rz3 = rz2

rxyz3 will be your final rotated coordinates
oh, sorry about that :oops: its good that someone knows :wink:
Pages: 1 2