Allright, here's the full code.
X + Y rotations seem so almost work, although they just seem to shrink and stretch (instead of a real rotation), and most angles on X or Y rotations make the wireframe look too small
It's something to do with the perspective, I believe, but I cannot figure it out.. calling all QB coders or trig experts or BASIC 3d programmers to please give a hand =)
A Z-axis rotation works fine...
I put comments throughout the code explaining stuff.
Sorry if my code is hard to understand =(
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