11-29-2003, 04:44 AM
I am doing 3D rotations.
Plllllllease help me, I'm sure it's a small problem that I'm just not seeing.. lol
Rotations about Z-axis work fine.
However about X and about Y-axises do not work
I hope my code makes sense to everyone =)
Plllllllease help me, I'm sure it's a small problem that I'm just not seeing.. lol
Rotations about Z-axis work fine.
However about X and about Y-axises do not work
I hope my code makes sense to everyone =)
Code:
DECLARE SUB Draw3D (WF() AS ANY, R!, XR!, YR!)
DECLARE SUB Draw3DE (WF() AS ANY, R!, XR!, YR!)
'Perspective Functions
DECLARE FUNCTION X2D (X, Z) 'Convert X,Z to X (used only by Draw3D + Draw3DE)
DECLARE FUNCTION Y2D (Y, Z) 'Convert Y,Z to Y (used only by Draw3D + Draw3DE)
'Drawing Subroutines
DECLARE SUB Draw3D (WF() AS ANY, R, XR, YR) 'Draws a wireframe
'Uses functions to rotate each point in the Wireframe
DECLARE SUB Draw3DE (WF() AS ANY, R, XR, YR) 'Erases wireframe, shows stats
'Uses functions to rotate each point in the Wireframe
'Performs rotations by reference of variables
DECLARE SUB RX (Y, Z, R) 'Rotates about X axis (not working), used by Draw3D
DECLARE SUB RZ (Y, X, R) 'Rotates about Y axis (not working), used by Draw3D
DECLARE SUB RY (X, Z, R) 'Rotates about Z axis (working), used by Draw3D
TYPE Wireframe
X AS INTEGER '3D X Coordinant
Y AS INTEGER '3D Y Coordinant
Z AS INTEGER '3D Z Coordinant
'A,B,C can be used to link to points(another subscript in the
'array)
A AS INTEGER
B AS INTEGER
C AS INTEGER
END TYPE
SCREEN 12
CLS
PRINT "Which rotation to perform? (X/Y/Z)";
DO
K$ = UCASE$(INKEY$)
LOOP UNTIL K$ = "X" OR K$ = "Y" OR K$ = "Z"
'Sets the option to 1, because the angle is multiplied by 1 or 0 to tell
'Draw3D the rotation.
IF K$ = "X" THEN XXR = 1
IF K$ = "Y" THEN YYR = 1
IF K$ = "Z" THEN ZZR = 1
DIM SHARED HSRX, HSRY
HSRX = 320
HSRY = 240
'Used for perceptective... I don't think this would cause the rotation
'problem.
DIM Cube(8) AS Wireframe
'This is our wireframe
Cube(1).X = 100
Cube(1).Y = 100
Cube(1).Z = 1
Cube(1).A = 2
Cube(1).B = 5
Cube(2).X = 200
Cube(2).Y = 100
Cube(2).Z = 1
Cube(2).A = 4
Cube(2).B = 6
Cube(3).X = 100
Cube(3).Y = 200
Cube(3).Z = 1
Cube(3).A = 1
Cube(3).B = 7
Cube(4).X = 200
Cube(4).Y = 200
Cube(4).Z = 1
Cube(4).A = 3
Cube(4).B = 8
Cube(5).X = 150
Cube(5).Y = 150
Cube(5).Z = 2
Cube(5).A = 6
Cube(6).X = 250
Cube(6).Y = 150
Cube(6).Z = 2
Cube(6).A = 8
Cube(7).X = 150
Cube(7).Y = 250
Cube(7).Z = 2
Cube(7).A = 5
Cube(7).B = 8
Cube(8).X = 250
Cube(8).Y = 250
Cube(8).Z = 2
Cube(8).A = 8
'Call Drawing subs and rotate from 1* to 360*
FOR X = 1 TO 360 STEP 1
Draw3D Cube(), ZZR * X, XXR * X, YYR * X
IF X < 360 THEN Draw3DE Cube(), ZZR * X, XXR * X, YYR * X
NEXT X
SUB Draw3D (WF() AS Wireframe, R, XR, YR)
FOR PNT = 1 TO 8
XX = WF(PNT).X
YY = WF(PNT).Y
ZZ = WF(PNT).Z
'Get points into 3 variables
'Check for rotation parameters
'and rotate points
IF R > 0 THEN CALL RZ(YY, XX, R)
IF XR > 0 THEN CALL RX(YY, ZZ, XR)
IF YR > 0 THEN CALL RY(XX, ZZ, YR)
'Get the X and Y from x,y,z
X = X2D(XX, ZZ)
Y = Y2D(YY, ZZ)
'Place a color-coded circle on the point
CIRCLE (X, Y), 3, PNT
'Check for links, rotate them if needed, get X & Y, then draw a line.
IF WF(PNT).A > 0 THEN
A = WF(PNT).A
AX = WF(A).X
AY = WF(A).Y
AZ = WF(A).Z
IF R > 0 THEN CALL RZ(AY, AX, R)
IF XR > 0 THEN CALL RX(AY, AZ, XR)
IF YR > 0 THEN CALL RY(AX, AZ, YR)
xa = X2D(AX, AZ)
ya = Y2D(AY, AZ)
LINE (X, Y)-(xa, ya), 4
END IF
IF WF(PNT).B > 0 THEN
A = WF(PNT).B
AX = WF(A).X
AY = WF(A).Y
AZ = WF(A).Z
IF R > 0 THEN CALL RZ(AY, AX, R)
IF XR > 0 THEN CALL RX(AY, AZ, XR)
IF YR > 0 THEN CALL RY(AX, AZ, YR)
xa = X2D(AX, AZ)
ya = Y2D(AY, AZ)
LINE (X, Y)-(xa, ya), 4
END IF
IF WF(PNT).C > 0 THEN
A = WF(PNT).C
AX = WF(A).X
AY = WF(A).Y
AZ = WF(A).Z
IF R > 0 THEN CALL RZ(AY, AX, R)
IF XR > 0 THEN CALL RX(AY, AZ, XR)
IF YR > 0 THEN CALL RY(AX, AZ, YR)
xa = X2D(AX, AZ)
ya = Y2D(AY, AZ)
LINE (X, Y)-(xa, ya), 4
END IF
NEXT
END SUB
SUB Draw3DE (WF() AS Wireframe, R, XR, YR)
LOCATE 1, 1
COLOR 15
PRINT "Z Rotation:"; R; "X Rotation:"; XR; "Y Rotation:"; YR
FOR PNT = 1 TO 8
XX = WF(PNT).X
YY = WF(PNT).Y
ZZ = WF(PNT).Z
IF R > 0 THEN CALL RZ(YY, XX, R)
IF XR > 0 THEN CALL RX(YY, ZZ, XR)
IF YR > 0 THEN CALL RY(XX, ZZ, YR)
COLOR PNT
PRINT "("; LTRIM$(RTRIM$(STR$(PNT))); ")X:"; XX; "Y:"; YY; "Z:"; ZZ;
X = X2D(XX, ZZ)
Y = Y2D(YY, ZZ)
PRINT "NX:"; X; "NY:"; Y
CIRCLE (X, Y), 3, 0
IF WF(PNT).A > 0 THEN
A = WF(PNT).A
AX = WF(A).X
AY = WF(A).Y
AZ = WF(A).Z
IF R > 0 THEN CALL RZ(AY, AX, R)
IF XR > 0 THEN CALL RX(AY, AZ, XR)
IF YR > 0 THEN CALL RY(AX, AZ, YR)
xa = X2D(AX, AZ)
ya = Y2D(AY, AZ)
LINE (X, Y)-(xa, ya), 0
END IF
IF WF(PNT).B > 0 THEN
A = WF(PNT).B
AX = WF(A).X
AY = WF(A).Y
AZ = WF(A).Z
IF R > 0 THEN CALL RZ(AY, AX, R)
IF XR > 0 THEN CALL RX(AY, AZ, XR)
IF YR > 0 THEN CALL RY(AX, AZ, YR)
xa = X2D(AX, AZ)
ya = Y2D(AY, AZ)
LINE (X, Y)-(xa, ya), 0
END IF
IF WF(PNT).C > 0 THEN
A = WF(PNT).C
AX = WF(A).X
AY = WF(A).Y
AZ = WF(A).Z
IF R > 0 THEN CALL RZ(AY, AX, R)
IF XR > 0 THEN CALL RX(AY, AZ, XR)
IF YR > 0 THEN CALL RY(AX, AZ, YR)
xa = X2D(AX, AZ)
ya = Y2D(AY, AZ)
LINE (X, Y)-(xa, ya), 0
END IF
NEXT
END SUB
SUB RX (Y, Z, R)
Rad = R * (3.14 / 180) 'Converts degrees to radians
YY = (Y * COS(Rad)) - (Z * SIN(Rad)) 'Performs y rotation
ZZ = (Y * SIN(Rad)) - (Z * COS(Rad)) 'Performs z rotation
Y = YY 'changes Y,Z
Z = ZZ
END SUB
SUB RY (X, Z, R)
Rad = R * (3.14 / 180)
XX = (Z * SIN(Rad)) + (X * COS(Rad))
ZZ = (Z * COS(Rad)) - (X * SIN(Rad))
X = XX
Z = ZZ
END SUB
SUB RZ (Y, X, R)
Rad = R * (3.14 / 180)
XX = (X * COS(Rad)) - (Y * SIN(Rad))
YY = (X * SIN(Rad)) + (Y * COS(Rad))
X = XX
Y = YY
END SUB
FUNCTION X2D (X, Z)
X2D = X / Z + HSRX
END FUNCTION
FUNCTION Y2D (Y, Z)
Y2D = Y / Z + HSRY
END FUNCTION