Replying to:spaceturtles
Is the equation used to generate the chart in the screenshot the same as the default or what is it?
Well, that's the 3D grapher, so the equation in the screenshot was Y=SIN(X)+COS(Z)
It can graph any function
Root / Submissions / [.]
PRGEDIT 3 EXEC "PRG3:3D.ENGINE" ENDDoing so will load the 3D engine into program slot 3, then insert the code from program slot 0 into program slot 3, then execute itself.
PRGEDIT 3 EXEC "PRG3:3D.ENGINE" END 'S1M.3D VAR C=ADDCUBE(0,0,0,1,1,1,#GRAY) 'C CONTAINS A REFERENCE TO THE CUBE @LOOP VSYNC 'STABALIZE THE FRAMERATE ROTOBJ C,0,1,0 'ROTATE THE CUBE AROUND THE Y AXIS RENDER 'RENDER THE WORLD GOTO @LOOP 'REPEATThere are a few things to be aware of before diving into the 3D engine
VAR CAMX,CAMY,CAMZ 'THE FOCUS POSITION OF THE CAMERA (DEFAULT: 0,0,0) VAR CAMRX,CAMRY,CAMRZ 'ROTATION OF THE CAMERA (IN DEGREES) AROUND THE CAMERA FOCUS (DEFAULT: 0,20,0) VAR CAMDIST 'DISTANCE AWAY FROM CAMERA'S FOCUS POINT (DEFAULT: 10) VAR FOV 'FIELD OF VIEW (DEFAULT: 5) VAR WSC 'WORLD SCALING CONSTANT IN PIXELS (DEFAULT: 50) VAR CUTOFF_RATIO 'THE RATIO BETWEEN CAMERA AND FOCUS IN WHICH THINGS STOP RENDERING (DEFAULT: 0.7) VAR BOUNDCAMANGLES 'TRUE/FALSE, TELL IF THE CAMERA SHOULD BE BOUNDED BETWEEN -180 AND 180 (DEFAULT: 1) VAR RENDERDIST 'HOW FAR THE PLACER CAN SEE, 0=INFINITE (DEFAULT: 0) VAR ACCELERATED_RENDERING 'TRUE/FALSE TO USE ADVANCED SOUND DLC (DEFAULT: 1 IF POSSIBLE) VAR FPS 'FRAMES PER SECOND VAR GMW0,GMH0 'WHERE THE SCREEN STARTS (DEFAULT: 0,0) VAR GMW1,GMH1 'WHERE THE SCREEN ENDS (DEFAULT: 400,240) VAR GMW05,GMH05 'DEFINES THE CENTER OF THE SCREEN TO SAVE COMPUTATIONAL OVERHEADHere are the preset object definitions:
ADDCUBE(X,Y,Z,LENGTH,WIDTH,HEIGHT,COLOR) 'CREATE A RECTANGULAR PRISM, RETURN ITS INDEX ADDWCUBE(X,Y,Z,LENGTH,WIDTH,HEIGHT,COLOR) 'CREATE A WIREFRAME RECTANGULAR PRISM, RETURN ITS INDEX ADDSPHERE(X,Y,Z,RADIUS,COLOR) 'CREATE A SPHERE, RETURN ITS INDEX ADDLINE(X1,Y1,Z1,X2,Y2,Z2,COLOR) 'CREATE A LINE, RETURN ITS INDEX ADDPYRAMID(X,Y,Z,WIDTH,HEIGHT,COLOR) 'CREATE A SQUARE PYRAMID, WHERE THE BASE OF THE BOTTOM IS X,Y,Z 'RETURNS THE OBJECT'S INDEX ADDDIAMOND(X,Y,Z,WIDTH,HEIGHT,COLOR) 'CREATE A DIAMOND SHAPE (A.K.A OCTAHEDRON) 'RETURNS THE OBJECT'S INDEX ADDCRYSTAL(X,Y,Z,WIDTH,HEIGHT,COLOR) 'CREATE A DIFFERENT TYPE OF "DIAMOND" SHAPE 'RETURNS THE OBJECT'S INDEX ADDSKYBOX(X,Y,Z,LENGTH,WIDTH,HEIGHT,COLOR) 'CREATE AN INSIDE-OUT CUBE THAT ACTS AS A SKYBOX WHEN LARGE 'RETURNS THE OBJECT'S INDEX ADDSURFACE(X,Y,Z,GRIDX,GRIDY,LENGTH,WIDTH,COLOR) 'CREATE A FLAT GRID PLANE THAT CAN HAVE MATH EQUATIONS APPLIED TO IT 'RETURNS ITS INDEX ADDFLAG(X,Y,Z,COLOR) 'CREATE A FLAG CHARACTER OBJECT (FROM 3D PARKOUR) 'RETURNS ITS INDEX ADDTEXT X,Y,Z,TEXT$,COLOR 'MAKE A TEXT OBJECT IN THE WORLD 'RETURNS THE OBJECT'S INDEXYou may also consider defining your own object
ADDOBJ(TYPE$,X[],Y[],Z[],COLOR) 'X[],Y[],Z[] DEFINE EACH TRIANGLE. THESE ARRAYS MUST BE IN SETS OF 3, SO LENGTH=3,6,9,12,15,18,...Every object contains these variables:
OBJX 'CENTER OF MASS X POSITION OBJY 'CENTER OF MASS Y POSITION OBJZ 'CENTER OF MASS Z POSITION OBJTEXT$ 'A STRING (USED IN TEXT OBJECTS) OBJTAG$ 'A STRING ONJTYPE$ 'A STRING TELLING WHAT TYPE OF OBJECT IT IS OBJINDEX 'THE INDEX POINTING TO WHICH TRIANGLES BELONG TO THIS OBJECT OBJLENGTH 'THE LENGTH OF HOW MANY TRIANGLES BELONG TO THIS OBJECT OBJRX 'GET (NO SET) THE OBJECT'S X ROTATION OBJRY 'GET (NO SET) THE OBJECT'S Y ROTATION OBJRZ 'GET (NO SET) THE OBJECT'S Z ROTATION OBJSX 'GET (NO SET) THE OBJECT'S X SCALE (WIDTH) OBJSY 'GET (NO SET) THE OBJECT'S Y SCALE (HEIGHT) OBJRZ 'GET (NO SET) THE OBJECT'S Z SCALE (LENGTH) OBJMINX 'GET (NO SET) THE OBJECT'S MINIMUM X VALUE OBJMINY 'GET (NO SET) THE OBJECT'S MINIMUM Y VALUE OBJMINZ 'GET (NO SET) THE OBJECT'S MINIMUM Z VALUE OBJMAXX 'GET (NO SET) THE OBJECT'S MAXIMUM X VALUE OBJMAXY 'GET (NO SET) THE OBJECT'S MAXIMUM Y VALUE OBJMAXZ 'GET (NO SET) THE OBJECT'S MAXIMUM Z VALUE OBJVX 'THE OBJECT'S X VELOCITY OBJVY 'THE OBJECT'S Y VELOCITY OBJVZ 'THE OBJECT'S Z VELOCITY OBJVISSTATIC 'TRUE/FALSE, IF THE OBJECT IS AFFECTED BY PHYSICS OBJMASK 'WHEN YOU DEFINE AN OBJECT YOU ARE GIVEN A MASK INDEX WHICH WILL NEVER 'CHANGE, SO YOU CAN ONLY ACCESS THE VARIABLES ABOVE BY GOING THROUGH THE OBJECT MASK 'FIRST: OBX[OBJMASK[MY_OBJECT_INDEX]]=FOO 'BY USING THIS MASK, WE CAN GUARANTEE THAT AN OBJECT INDEX WILL NEVER CHANGE 'EVEN IF OBJECTS BEFORE IT ARE DELETED.Here is a list of object functions
STRETCHOBJ INDEX,SCALEX,SCALEY,SCALEZ 'SQUISHES OR STRETCHES AN OBJECT'S POINTS BY A GIVEN SCALE MOVEOBJ INDEX,DX,DY,DZ 'INCREMENT AN OBJECT'S POSITION RELATIVE TO ITS CURRENT POSITION MOVEOBJTO INDEX,X,Y,Z 'TELEPORT AN OBJECT SOMEWHERE (NOT RELATIVE) ROTOBJ INDEX,AX,AY,AZ 'INCREMENT THE ROTATION OF AN OBJECT AROUND ITS CENTER OF MASS RELATIVE TO ITS CURRENT ROTATION ROTOBJTO INDEX,AX,AY,AZ 'SET THE ROTATION OF AN OBJECT AROUND ITS CENTER OF MASS (NOT RELATIVE) 'THIS WILL RESET THE OBJECT'S ROTATION TO ITS DEFAULT, THEN ROTATE IT AX,AY,AZ ROTOBJAROUND INDEX,X,Y,Z,AX,AY,AZ 'ROTATE AN OBJECT AROUND (X,Y,Z) ROTOBJAROUNDOBJ INDEX,INDEX2,AX,AY,AZ 'ROTATE AN OBJECT AROUND ANOTHER OBJECT ROTOBJTOPOINT INDEX,X,Y,Z 'ROTATE AN OBJECT SO THAT IT FACES THE POINT X,Y,Z MERGEOBJS(INDEX1,INDEX2) 'MERGE TWO OBJECTS INTO ONE, RETURNS THE NEW INDEX SPLITOBJ INDEX,TRIANGLES OUT INDEX1,INDEX2 'SPLIT AN OBJECT AT A TRIANGLE INDEX, DEFINING THE AMOUNT OF TRIANGLES FOR THE FIRST OBJECT DELOBJ INDEX : INDEX=-1 'DELETE AN OBJECT FROM THE WORLD 'THEN IT IS RECOMMENDED TO SET THE INDEX TO -1 CHANGEOBJCOLOR INDEX,COLOR 'SET AN OBJECT'S COLOR CHANGEOBJFACECOLOR INDEX,FACE,COLOR 'SET THE COLOR OF A SINGLE TRIANGLE ON AN OBJECT CHANGEOBJCOLORAB OBJECT,INDEX1,INDEX2,COLOR 'SET AN OBJECT'S COLOR FROM INDEX1 TO INDEX2 INSIDE THE OBJECT 'OBJECT TRIANGLE INDEXES START AT 0 FOR EACH OBJECT SETTAG INDEX,TAG$ 'GIVE AN OBJECT A STRING, DEFAULT="" 'THIS CAN BE ANYTHING, IT DOESN'T AFFECT THE 3D ENGINE AT ALL 'DESIGNED TO BE USED BY THE DEVELOPER GETTAG$(INDEX) 'GET THE TAG$ VALUE OF AN OBJECT FINDIBJBYTAG(TAG$) 'QUICKLY FIND AN OBJECT WITH A SPECIFIC TAG$ VALUE 'RETURNS -1 IF NO OBJECT EXISTS WITH THIS TAG SETSTR INDEX,S$ 'GIVE AN OBJECT A STRING, DEFAULT="" 'THIS IS USED TO STORE THE VALUE IN TEXT OBJECTS 'THERE IS NO USE OUTSIDE OF TEXT OBJECTS, SO THIS IS ANOTHER FREE VARIABLE GETSTR$(INDEX) 'GET THE STRING VALUE OF AN OBJECT FINDIBJBYSTR(S$) 'FIND AN OBJECT WITH A SPECIFIC STRING$ VALUE 'RETURNS -1 IF NO OBJECT EXISTS WITH THIS STRING 'OTHERWISE RETURN THE OBJECT INDEX GETOBJTYPE$(INDEX) 'RETURNS THE STRING DEFINING WHAT TYPE OF OBJECT IT IS 'POSSIBLE RESULTS ARE: "CUBE","SPHERE","DIAMOND","CRYSTAL","PYRAMID","SKYBOX","LINE","SURFACE","TEXT",etc... GETOBJSBYDIST(X,Y,Z) 'RETURNS A SORTED ARRAY OF OBJECT INDEXES SUCH THAT THE FIRST ITEM IS CLOSEST 'TO (X,Y,Z) AND THE LAST ITEM IS FURTHEST AWAY FROM (X,Y,Z) 'THIS FUNCTION TAKES ADVANTAGE OF DLC USERS TO GIVE MUCH FASTER PERFORMANCE UPDATEWCUBEAROUNDOBJ INDEX1,INDEX2 'CHANGE THE WIREFRAME CUBE OBJECT INSIDE INDEX1 TO THE SAME SHAPE AND 'SIZE OF THE OBJECT INSIDE INDEX2 (INDEX1 MUST BE A WCUBE OBJECT) 'IN OTHER WORDS, THIS IS AN ADD-ON TO THE WCUBE OBJECT TO ALLOW IT TO 'PERFECTLY MASK THE BOUNDING BOX OF ANOTHER OBJECT APPLYSURFACEEQUATION INDEX,EQU$,MINY,MAXY,SCX,SCY,SCZ 'APPLY A MATH EXPRESSION TO A SURFACE OBJECT 'EQU$ IS AN EQUATION WITH X,Y, AND Z IN IT 'EQU$="SIN(X)+COS(Z)" MAKES A WAVY SURFACE 'MINY AND MAXY DEFINE THE OBJECT'S Y BOUNDS 'SCX,SCY,SCZ ARE THE ZOOM FACTORS, 0.1=>10X ZOOM 'IN OTHER WORDS, THIS IS AN ADD-ON TO SURFACES, ALLOWING 'THEM TO TAKE ON THE FORM OF ANY EQUATION GETUNMASKEDINDEX(MASKEDINDEX) 'SAME AS SAYING OBJMASK[MASKEDINDEX] 'CONVERTS A STABLE OBJECT ID (THAT DOESN'T CHANGE) INTO 'THE ACTUAL INDEX USED IN OBJX,OBJY,OBJZ,OBJROT,etc... UPDATEOBJCENTER INDEX 'UPDATES THE CENTER OF MASS OF AN OBJECT (DONE AUTOMATICALLY) SETSTATICOBJ INDEX,STATE 'SET IF AN OBJECT IS AFFECTED BY GRAVITY AND COLLISIONS 'STATE IS EITHER 1 OR 0 (WHERE 0=AFFECTED BY GRAVITY) ADDVEL INDEX,VX,VY,VZ 'ADD VELOCITY TO A NON-STATIC OBJECT 'YOU COULD ALSO JUST DO: 'INC OBJVX[OBJMASK[INDEX]],VX 'INC OBJVY[OBJMASK[INDEX]],VY 'INC OBJVZ[OBJMASK[INDEX]],VZAnd a few other functions, slightly unrelated, but implemented nonetheless:
RENDER 'DRAWS THE CURRENT WORLD STATE, REQUIRED TO RUN ONCE EVERY FRAME BUFFER 'PREVENTS FLICKERING BY SWAPPING GPAGES EACH FRAME, DRAWING TO THE ONE NOT 'BEING SHOWN. THIS SHOULD BE RAN ONCE EVERY FRAME, WITH A GCLS DIRECTLY AFTER IT 'THIS ONLY AFFECTS THE TOP SCREEN 'THIS IS AUTOMATICALLY CALLED INSIDE RENDER _RENDER 'RENDERS THE SCENE WITHOUT CALLING BUFFER AND CLEARING THE SCREEN BUFFERBOTTOM 'PREVENT FLICKERING ON THE LOWER SCREEN, PUT GCLS DIRECTLY AFTER IT GETCAMRAY OUT X,Y,Z 'RETURNS THE NORMALIZED DIRECTION THE CAMERA IS FACING GETCAMRAY2D OUT X,Z 'RETURNS THE NORMALIZED DIRECTION THE CAMERA IS FACING EXCLUDING Y RAYTHROUGHOBJ(X,Y,Z,RX,RY,RZ,INDEX) 'CHECK IF THE RAY STARTING AT X,Y,Z AT THE ANGLE RX,RY,RZ 'IS COLLIDING WITH THE OBJECT INSIDE INDEX NORMALIZE X,Y,Z OUT X,Y,Z 'SET THE DISTANCE OF AN X,Y,Z DISPLACEMENT EQUAL TO 1 'WHILE MAINTAINING THE ANGLE CLEARWORLD 'DELETES EVERYTHING IN THE WORLD 'TRIANGLE OPERATION FUNCTIONS ADDTRI INDEX,TAG$,X1,Y1,Z1,X2,Y2,Z2,X3,Y3,Z3,COLOR SETTRI INDEX,X1,Y1,Z1,X2,Y2,Z2,X3,Y3,Z3 'SET A TRIANGLES POSITION DELTRI TRIANGLEINDEX 'DELETE A TRIANGLE SPLITSCREENDRAW X1,Y1,Z1,RX1,RY1,RZ1,X2,Y2,Z2,RX2,RY2,RZ2 'REPLACES THE RENDER FUNCTION 'DRAWS TWO PERSPECTIVES FROM TWO CAMERA POSITIONS AND ANGLES '[ UNDER CONSTRUCTION, STILL A BIT BUGGY ] QUADRUPLEDRAW X1,Y1,Z1,RX1,RY1,RZ1,X2,Y2,Z2,RX2,RY2,RZ2,X3,Y3,Z3,RX3,RY3,RZ3,X4,Y4,Z4,RX4,RY4,RZ4 'REPLACES THE RENDER FUNCTION 'DRAWS FOUR PERSPECTIVES FROM FOUR CAMERA POSITIONS AND ANGLES '3D POINT ROTATION FUNCTIONS ROT X,Y,Z,ORIGINX,ORIGINY,ORIGINZ,ANGLEX,ANGLEY,ANGLEZ OUT X,Y,Z ROTX X,Y,Z,ANGLE OUT X,Y,Z 'ROTATE A POINT JUST AROUND X AXIS ROTY X,Y,Z,ANGLE OUT X,Y,Z 'ROTATE A POINT JUST AROUND Y AXIS ROTZ X,Y,Z,ANGLE OUT X,Y,Z 'ROTATE A POINT JUST AROUND Z AXIS INSERT ARRAY[],INDEX,VALUE 'QUICKLY INSERT AN ELEMENT INTO AN ARRAY REMOVE ARRAY[],INDEX 'QUICKLY REMOVE AN ELEMENT FROM AN ARRAY TRIM$(S$) 'REMOVE SPACES AND NEW LINES FROM THE FRONT AND END OF A STRING 'HSV OPERATIONS HSV2RGB HUE,SATURATION,VALUE OUT RED,GREEN,BLUE RGB2HSV RED,GREEN,BLUE OUT HUE,SATURATION,VALUE HSV(HUE,SATURATION,VALUE) 'RETURNS THE COLOR AS A SINGLE NUMBER, JUST LIKE RGB(R,G,B) DOES FCIRCLE X,Y,RADIUS,FILLCOLOR,BORDERCOLOR 'DRAW A FILLED CIRCLE TEXT X,Y,TEXT$,COLOR 'DRAW CENTERED TEXT ON THE SCREEN PERSPECTIVE X,Y,Z OUT X,Y,Z 'CONVERT IN-WORLD COORDINATES TO SCREEN COORDINATES PERSPECTIVEZ(X,Y,Z) 'QUICKLY JUST CALCULATE THE Z VALUE AFTER PERSPECTIVE ARYOP_PERSPECTIVE X[],Y[],Z[] OUT X[],Y[],Z[] 'CALCULATE FASTER PERSPECTIVE
PRGEDIT 3 EXEC "PRG3:3D.ENGINE" END 'SIM.3D VAR STX,STY,C 'POSITION (0,0,0) SIZE (1,1,1) C=ADDCUBE(0,0,0,1,1,1,#GRAY) C=ADDCUBE(0,1.5,0,1,1,1,#GREEN) C=ADDCUBE(1.5,0,0,1,1,1,#CYAN) C=ADDCUBE(0,0,1.5,1,1,1,#WHITE) C=ADDCUBE(0,0,3,0.5,0.5,0.5,HSV(0,255,255)) 'THE VARIABLE C WAS OVERWRITTEN OVER AND OVER, BUT THIS ONE WE'LL KEEP @LOOP VSYNC STICK OUT STX,STY 'CAMRX,CAMRY ARE USED BY SIM.3D CAMRX=CAMRX-STX*5 CAMRY=CAMRY-STY*5 'ROTATE THE CUBE AROUND THE POINT (0,0,0) ROTATING AROUND THE X AND Y AXIS ROTOBJAROUND C,0,0,0,1,1,0 RENDER GOTO @LOOPYou are a cube, you can rotate your camera and move around the world. In the world there is a large 3D Sierpinski tetrahedron fractal generated recursively
PRGEDIT 3 EXEC "PRG3:3D.ENGINE" VAR I,J 'MAKE AN INSIDE OUT CUBE CENTERED AT POSITION (0,5,50) AND SIZE (120,120,120) I=ADDSKYBOX(0,5,50,120,120,120,RGB(60,60,60)) VAR PLAYER=ADDCUBE(0,0,0,1,1,1,#WHITE) VAR BTN,STX,STY,X,Y,Z 'CALL THE FUNCTION THAT GENERATES THE FRACTAL 'POSITION=(0,30,50) 'SIZE=(40,50) 'DEPTH=3 '(HUE,SATURATION,VALUE)=(RND(360),150,255) SIERPINSKI 0,30,50,40,50,3,RND(360),150,255 @LOOP VSYNC CLS PRINT "FPS ";FPS 'FPS IS CALCULATED INSIDE SIM.3D 'EVERY FRAME, SET THE PLAYER CUBE TO THE SAME POSITION AS THE CAMERA MOVEOBJTO PLAYER,CAMX,CAMY,CAMZ CONTROLS 'CALL THE FUNCTION THAT HANDLES CONTROLS 'PREVENT THE CAMERA FROM GOING UPSIDE DOWN IF CAMRY<-90 THEN CAMRY=-90 IF CAMRY>90 THEN CAMRY=90 RENDER 'CALL THE RENDER FUNCTION IN SIM.3D GOTO @LOOP 'HANDLE DEVICE CONTROLS DEF CONTROLS STICK OUT STX,STY 'CIRCLE PAD INPUT BTN=BUTTON() 'INPUT FOR BUTTONS 'ROTATE THE CAMERA, USE COSINE TO ENSURE IT IS ALIGNED DEC CAMRX,STX*6*COSCAMRZ DEC CAMRY,STY*6*COSCAMRZ IF BTN AND #UP THEN CAMDIST=CAMDIST/1.05 'ZOOMING IN/OUT IF BTN AND #DOWN THEN CAMDIST=CAMDIST*1.05 IF BTN AND #X THEN 'MOVING FORWARD VAR X,Y,Z GETCAMRAY OUT X,Y,Z 'THIS WILL GIVE THE X,Y,Z UNIT ROTATION FACING OUT OF THE CAMERA INC CAMX,X/2 'INCREMENT THE CAMERA POSITION INC CAMY,Y/2 INC CAMZ,Z/2 ENDIF IF BTN AND #B THEN 'MOVING BACKWARD VAR X,Y,Z GETCAMRAY OUT X,Y,Z 'THIS WILL GIVE THE X,Y,Z UNIT ROTATION FACING OUT OF THE CAMERA DEC CAMX,X/2 'DECREMENT THE CAMERA POSITION DEC CAMY,Y/2 DEC CAMZ,Z/2 ENDIF END 'GENERATE A SIERPINSKI TETRAHEDRON FRACTAL 'POSITION=(X,Y,Z) 'SIZE=(WIDTH,HEIGHT) (LENGTH ISN'T INCLUDED SINCE ITS A SQUARE BASE) 'DEPTH IS HOW MANY ITERATIONS TO GO IN (PERFORMANCE TAKES A HUGE HIT, INCREMENTING) 'COLOR=(HUE,SATURATION,VALUE) DEF SIERPINSKI X,Y,Z,W_,H_,DEPTH,HU,SA,VA VAR I,W=W_*0.5,H=H_*0.5 IF DEPTH==0 THEN 'BASE CASE I=ADDPYRAMID(X,Y,Z,W_*2,H_,HSV(HU,SA,VA)) ELSE SIERPINSKI X,Y-H,Z,W,H,DEPTH-1,HU+100,SA,VA SIERPINSKI X-W,Y,Z-W,W,H,DEPTH-1,HU,SA,VA SIERPINSKI X-W,Y,Z+W,W,H,DEPTH-1,HU,SA,VA SIERPINSKI X+W,Y,Z-W,W,H,DEPTH-1,HU,SA,VA SIERPINSKI X+W,Y,Z+W,W,H,DEPTH-1,HU,SA,VA ENDIF END
PRGEDIT 2:EXEC "PRG2:3D.LOADER"And then in the engine loader:
PRGDEL -1 PRGSET CODE$ EXEC 2