Qbasicnews.com

Full Version: 3D problems
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
As a graphics project for my computer science class, I decided to do a simple 3D program where the user moves around a plane with obstacles and whatnot. I have the entire program coded, but the 3D aspect isn't working (numlock has to be on)

Code:
DECLARE SUB Pyramid ()
DECLARE FUNCTION min! (a!, b!)
DECLARE FUNCTION max! (a!, b!)
RANDOMIZE TIMER
SCREEN 12
KEY 15, CHR$(128) + CHR$(75) 'left
KEY 16, CHR$(128) + CHR$(77) 'right
KEY 17, CHR$(128) + CHR$(72) 'up
KEY 18, CHR$(128) + CHR$(80) 'down
KEY 19, CHR$(0) + CHR$(1)
ON KEY(15) GOSUB left
ON KEY(16) GOSUB right
ON KEY(17) GOSUB up
ON KEY(18) GOSUB down
ON KEY(19) GOSUB donew:
KEY(15) ON
KEY(16) ON
KEY(17) ON
KEY(18) ON
KEY(19) ON
TYPE ThreeD
    X AS INTEGER
    y AS INTEGER
    Z AS INTEGER
END TYPE
TYPE LIN
    S AS INTEGER
    E AS INTEGER
END TYPE

DIM SHARED PyrTmp(6) AS ThreeD
DIM SHARED Cx
DIM SHARED Cy
DIM SHARED fld%(50, 50)
DIM SHARED Dir
CONST pi = 3.14159
Cx = 250 'Defaults to center of screen
Cy = 250


FOR X = 1 TO 49
    FOR y = 1 TO 49
        IF RND < .9 THEN
            fld%(X, y) = 1
        END IF

    NEXT y
NEXT X

FOR i = 1 TO 5
    READ PyrTmp(i).X, PyrTmp(i).y, PyrTmp(i).Z
NEXT i

DO
    COLOR 15
    Pyramid
LOOP

up:
    xoset = 0
    yoset = 0
    LINE (Cx, Cy)-STEP(11, 11), 0, BF
     xoset = COS(Dir) * 10
     yoset = SIN(Dir) * 10
     mfx = (Cx / 10 + xoset / 10)
     mfy = (Cy / 10 + yoset / 10)
     IF fld%(Cx / 10 + xoset / 10, Cy / 10 + yoset / 10) = 0 AND mfx * mfy >= 1 AND mfx < 50 AND mfy < 50 THEN
        Cx = Cx + xoset
        Cy = Cy + yoset
     END IF

RETURN

down:
    xoset = 0
    yoset = 0
    LINE (Cx, Cy)-STEP(11, 11), 0, BF
    mfx = (Cx / 10 + xoset / 10)
    mfy = (Cy / 10 + yoset / 10)
    xoset = COS(Dir) * 10
    yoset = SIN(Dir) * 10
    IF fld%(Cx / 10 + xoset / 10, Cy / 10 + yoset / 10) = 0 AND (mfx * mfy >= 0) AND mfx < 50 AND mfy < 50 THEN
        Cx = Cx - xoset
        Cy = Cy - yoset
     END IF
RETURN
right:
    Dir = Dir + pi * .1
    IF Dir > 2 * pi THEN Dir = 0
RETURN

left:
    Dir = Dir - pi * .1
    IF Dir < 0 THEN Dir = 2 * pi
RETURN
    
donew:
END
RETURN



'x,y,z
DATA 0,5,0
DATA -100,0,-10
DATA -100,0,10
DATA 10,0,-10
DATA 10,0,10

FUNCTION max (a, b)
max = b
IF a > b THEN max = a
END FUNCTION

FUNCTION min (a, b)
min = b
IF a < b THEN min = a
END FUNCTION

SUB Pyramid
DIM Pyr(6) AS ThreeD
DIM TX AS LIN
DIM Sx AS LIN
DIM Xf AS LIN
DIM Yf AS LIN
DIM Zf AS LIN
DIM FinX AS LIN
DIM FinY AS LIN

Rot = 2 * pi - Dir
Xmin% = max(Cx / 10, 0)
Xmax% = min(Cx / 10, 50)
Ymin% = max(Cy / 10, 0)
Ymax% = min(Cy / 10, 50)

FOR X = Ymin% TO Xmax%
    FOR y = Ymin% TO Ymax%
        IF fld%(X, y) THEN   'Read the array to see if an object exists
            FOR Start = 1 TO 5
                FOR EndL = Start TO 5
                    'Adjust coordinates relative to viewer
                    TX.S = PyrTmp(Start).X + (X * 10 - Cx)
                    TY.S = PyrTmp(Start).y + (y * 10 - Cy)
                    TZ.S = PyrTmp(Start).Z * 10
                    TX.E = PyrTmp(EndL).X + (X * 10 - Cx)
                    TY.E = PyrTmp(EndL).y + (y * 10 - Cy)
                    TZ.E = PyrTmp(EndL).Z * 10
                    'Rotates the grid
                    Sx.S = TX.S * COS(Rot) + TY.S * SIN(Rot)
                    Sy.S = TY.S * COS(Rot) + TX.S * SIN(Rot)
                    Sx.E = TX.E * COS(Rot) + TY.E * SIN(Rot)
                    Sy.E = TY.E * COS(Rot) + TX.E * SIN(Rot)
                    'Adjusts coordinates from (-1 TO 1,-1 TO 1) to (0 TO 640, 0 to 480)
                    Sx.S = Sx.S * 2 + 320
                    Sy.S = Sy.S * 2 + 240
                    Sx.E = Sx.E * 2 + 320
                    Sy.E = Sy.E * 2 + 240
                    '3D transformation
                    Xf.S = Sx.S / Sy.S
                    Yf.S = Sz.S / Sy.S
                    Xf.E = Sx.E / Sy.E
                    Yf.E = Sz.E / Sy.E
                  
                    LINE (Xf.S, Yf.S)-(Xf.E, Yf.E)
                NEXT EndL
            NEXT Start
        END IF
    NEXT y
NEXT X

END SUB
well, just by glancing at your code, i was able to make some assumptions. first off, i don't do 3d. i haven't even passed math a30 yet. but i still know some things...

1. don't use on key! instead, use inp(96). it's much nicer.

2. if you're using pi, instead of going

const pi = 3.14159

either go:

dim pi as double

const pi = 3.14159

or...

const pi# = 3.14159
num lock needs to be on? It works for me with num lock turned off. BTW first off dont use KEY function. Here is a proggie which will let you use the same keys irrespective of whether or not you have the numlock turned off.

Code:
CLS

DO
   KeyPress$ = INKEY$
  
   IF LEN(KeyPress$) = 2 THEN
      ScanCode% = ASC(RIGHT$(KeyPress$, 1))
   END IF

   IF KeyPress$ = CHR$(27) THEN LOCATE 1, 1: PRINT "You hit the ESC key!": END
  
   SELECT CASE ScanCode%
   CASE 72
      LOCATE 1, 1: PRINT "UP ARROW    "
   CASE 75
      LOCATE 1, 1: PRINT "LEFT ARROW  "
   CASE 77
      LOCATE 1, 1: PRINT "RIGHT ARROW "
   CASE 80
      LOCATE 1, 1: PRINT "DOWN ARROW  "
   CASE 59
      LOCATE 1, 1: PRINT "F1 Key      "
   END SELECT
   ScanCode% = 0
LOOP
is anything exsposed to appear on the screen or is that why it's not working?
For me, only some pixels appear on the upper left corner of the screen.

BTW m2k, do u know C? If so i can point you to an example which will do something similar to what you want.
Quote:For me, only some pixels appear on the upper left corner of the screen.
yeah me too
IMHO there is some problem with plotting. Somewhere the X, Y positions are being lost. I havent gone through the code much :roll:
i wish i could help... but just to make sure


Code:
FOR X = Ymin% TO Xmax%
    FOR y = Ymin% TO Ymax%
is that correct or should it be

Code:
FOR X = Xmin% TO Xmax%
    FOR y = Ymin% TO Ymax%
Don't know C, sorry.

@whitetiger: didn't notice that.

I've noticed that if I increase the size of the coordinates in DATA, then the object is more visible, but the rotation/movement still doesn't work.

I know that the movement should work, because when I was starting this, I did it all in 2D, and everything worked fine. I'll see if the error in the FOR loop will help this problem, but I doubt it as the problem lies in the 3D - 2D conversion.
Code:
'3D transformation
                    Xf.S = Sx.S / Sy.S
                    Yf.S = Sz.S / Sy.S
                    Xf.E = Sx.E / Sy.E
                    Yf.E = Sz.E / Sy.E

Sz.S is not used anywhere else (i think)
niether is Sz.E (i also think)
so wouldn't that be
'Yf.S = 0 / Sy.S' which is... always 0 no matter what Sy.S is.

ALSO:
Code:
DIM FinX AS LIN
DIM FinY AS LIN
is there a point to these?
Pages: 1 2