Lesson 3: Different shapes
In this lesson we will change our code to show different shapes.
Changing the initialization
Our first problem is that different shapes will probably have different numbers of points and edges and we need be able to store the different objects in our arrays POINTS and EDGES.
So we setup two new constants for the maximum number of points and edges the different objects are allowed to have and create the arrays accordingly:
REM OBJECTS CAN HAVE NO MORE THAN 30 POINTS MAXNUMBEROFPOINTS = 30 NUMBEROFDIMENSIONS = 2 DIM POINTS(MAXNUMBEROFPOINTS - 1, NUMBEROFDIMENSIONS - 1) IDXX = 0 IDXY = 1 REM OBJECTS CAN HAVE NO MORE THAN 30 EDGES MAXNUMBEROFEDGES = 30 NUMBEROFPOINTSOFANEDGE = 2 DIM EDGES(MAXNUMBEROFEDGES - 1, NUMBEROFPOINTSOFANEDGE - 1) IDXSTARTPOINT = 0 IDXENDPOINT = 1
(We will keep using the old variables NUMBEROFPOINTS and NUMBEROFEDGES later on as you’ll see.)
Then we change the data list for points and edges so that the first value holds the count of points or edges:
Additionally we change the label to the data of the rectangle a bit also:
DATAOFRECTANGLE: REM 4 POINTS FOLLOW DATA 4 DATA -20, -10 DATA 20, -10 DATA 20, 10 DATA -20, 10 REM 4 EDGES FOLLOW DATA 4 DATA 0, 1 DATA 1, 2 DATA 2, 3 DATA 3, 0
And now we change the reading of the points and edges so that it reads also the numbers of the points and the edges.
We put that into a subroutine called INITPOINTSANDEDGES:
INITPOINTSANDEDGES:
RESTORE DATAOFRECTANGLE
REM READ THE NUMBER OF POINTS FIRST
READ NUMBEROFPOINTS
REM THEN READ THE COORDINATES OF THE POINTS
FOR POINTNO = 0 TO NUMBEROFPOINTS - 1
READ POINTS(POINTNO, IDXX)
READ POINTS(POINTNO, IDXY)
NEXT POINTNO
REM READ NOW READ THE NUMBER OF EDGES
READ NUMBEROFEDGES
REM THEN READ THE START AND END POINT OF THE EDGES
FOR EDGENO = 0 TO NUMBEROFEDGES - 1
READ EDGES(EDGENO, IDXSTARTPOINT)
READ EDGES(EDGENO, IDXENDPOINT)
NEXT EDGENO
RETURN
More shapes
So now we will add some more data lines for other shapes.
Let’s think of a simple triangle:
P0
/ \
/ \
E2 C E0
/ \
/ \
P2---------E1--------P1
The data is as follows:
DATAOFTRIANGLE: REM 3 POINTS FOLLOW DATA 3 DATA 0, -10 DATA 10, 10 DATA -10, 10 REM 3 EDGES FOLLOW DATA 3 DATA 0, 1 DATA 1, 2 DATA 2, 0
Now let’s think of a more complex figure, a jet.
That’s the data of our jet:
DATAOFJET: REM 15 POINTS FOLLOW DATA 15 DATA 0, -8 DATA 1, -5 DATA 1, -2 DATA 6, 3 DATA 1, 3 DATA 1, 6 DATA 3, 8 DATA 0, 8 DATA 0, 5 DATA -3, 8 DATA -1, 6 DATA -1, 3 DATA -6, 3 DATA -1, -2 DATA -1, -5 REM 18 EDGES FOLLOW DATA 18 DATA 0,1 DATA 1,2 DATA 2,3 DATA 3,4 DATA 4,5 DATA 5,6 DATA 6,7 DATA 7,8 DATA 7,9 DATA 9,10 DATA 10,11 DATA 11,12 DATA 12,13 DATA 13,14 DATA 14,0 DATA 1,4 DATA 11,13 DATA 2,4
For our three different object types we create three constants:
REM CONSTANTS FOR THE OBJECT TYPES OBJTYPERECTANGLE = 0 OBJTYPETRIANGLE = 1 OBJTYPEJET = 2
Reading the shapes
We will now change our subroutine INITPOINTSANDEDGES a bit so that it reads the correct data for the chosen obj type OBJTYPE:
REM INIT POINTS AND EDGES
REM IN:
REM OBJTYPE: THE OBJECT TYPE TO BE READ
REM
INITPOINTSANDEDGES:
REM RESTORE TO THE RIGHT LABEL DEPENDING ON THE OBJECT TYPE
IF OBJTYPE = OBJTYPERECTANGLE THEN
RESTORE DATAOFRECTANGLE
ELSE IF OBJTYPE = OBJTYPETRIANGLE THEN
RESTORE DATAOFTRIANGLE
ELSE IF OBJTYPE = OBJTYPEJET THEN
RESTORE DATAOFJET
ELSE
PRINT "UNKNOWN OBJTYPE " + OBJTYPE
END
END IF
REM READ THE NUMBER OF POINTS FIRST
READ NUMBEROFPOINTS
REM THEN READ THE COORDINATES OF THE POINTS
FOR POINTNO = 0 TO NUMBEROFPOINTS - 1
READ POINTS(POINTNO, IDXX)
READ POINTS(POINTNO, IDXY)
NEXT POINTNO
REM NOW READ THE NUMBER OF EDGES
READ NUMBEROFEDGES
REM THEN READ THE START AND END POINT OF THE EDGES
FOR EDGENO = 0 TO NUMBEROFEDGES - 1
READ EDGES(EDGENO, IDXSTARTPOINT)
READ EDGES(EDGENO, IDXENDPOINT)
NEXT EDGENO
RETURN
Switching between the shapes
Before we start the main loop we will initialize our object as a rectangle. In the main loop we want to toggle through the object types with “B”:
REM INIT THE OBJECT THE FIRST TIME
OBJTYPE = OBJTYPERECTANGLE
GOSUB INITPOINTSANDEDGES
REM MAIN LOOP
DO
REM CLEAR SCREEN AND DRAW THE RECTANGLE
CLS
GOSUB CALCSCREENPOINTS
GOSUB DRAWEDGES
WAIT 0.04
REM WITHOUT ANY BUTTON PRESS WE MOVE THE RECTANGLE
IF UP(0) AND NOT BUTTON(0) THEN OBJPOSY = OBJPOSY - 1
IF DOWN(0) AND NOT BUTTON(0) THEN OBJPOSY = OBJPOSY + 1
IF LEFT(0) AND NOT BUTTON(0) THEN OBJPOSX = OBJPOSX - 1
IF RIGHT(0) AND NOT BUTTON(0) THEN OBJPOSX = OBJPOSX + 1
REM PRESSING BUTTON A AND UP OR DOWN CHANGES THE SCALE
IF DOWN(0) AND BUTTON(0) AND OBJSCALE > 0.1 THEN OBJSCALE = OBJSCALE - 0.1
IF UP(0) AND BUTTON(0) THEN OBJSCALE = OBJSCALE + 0.1
REM PRESSING BUTTON A AND LEFT OR RIGHT ROTATES THE OBJECT
IF LEFT(0) AND BUTTON(0, 1) THEN
REM TURN LEFT BY REDUCING OBJROTATION (AND THUS ROTATE COUNTERCLOCKWISE)
OBJROTATION = OBJROTATION - 0.1
REM IF WE PASS NORTH FROM THE RIGHT TO THE LEFT THEN WE NEED TO ADD 2 * PI
IF OBJROTATION < 0 THEN
OBJROTATION = OBJROTATION + 2 * PI
END IF
END IF
IF RIGHT(0) AND BUTTON(0, 1) THEN
REM TURN RIGHT BY INCREASING OBJROTATION (AND THUS ROTATE CLOCKWISE)
OBJROTATION = OBJROTATION + 0.1
REM IF WE PASS NORTH FROM THE LEFT TO THE RIGHT THEN WE NEED TO SUBSTRACT 2 * PI
IF OBJROTATION >= 2 * PI THEN
OBJROTATION = OBJROTATION - 2 * PI
END IF
END IF
REM IF BUTTON B IS PRESSED CHANGE OBJECT TO NEXT OBJECT TYPE
IF BUTTON(0, 2) THEN
OBJTYPE = OBJTYPE + 1
REM IF WE'RE OUT OF OBJECT TYPES RESTART AT THE RECTANGLE
IF OBJTYPE > OBJTYPEJET THEN
OBJTYPE = OBJTYPERECTANGLE
END IF
GOSUB INITPOINTSANDEDGES
END IF
LOOP
Ok, now let’s glue it all together and try it:
Open source code in LowResCoder app
REM VECTOR GRAPHICS - LESSON 3 - DIFFERENT SHAPES
REM BY TODDL
REM OBJECTS CAN HAVE NO MORE THAN 30 POINTS
MAXNUMBEROFPOINTS = 30
NUMBEROFDIMENSIONS = 2
DIM POINTS(MAXNUMBEROFPOINTS - 1, NUMBEROFDIMENSIONS - 1)
IDXX = 0
IDXY = 1
REM OBJECTS CAN HAVE NO MORE THAN 30 EDGES
MAXNUMBEROFEDGES = 30
NUMBEROFPOINTSOFANEDGE = 2
DIM EDGES(MAXNUMBEROFEDGES - 1, NUMBEROFPOINTSOFANEDGE - 1)
IDXSTARTPOINT = 0
IDXENDPOINT = 1
REM ARRAY FOR SCREEN POINTS
DIM SCREENPOINTS(MAXNUMBEROFPOINTS - 1, NUMBEROFDIMENSIONS - 1)
REM CONSTANTS FOR THE OBJECT TYPES
OBJTYPERECTANGLE = 0
OBJTYPETRIANGLE = 1
OBJTYPEJET = 2
SCREENCENTREX = 32
SCREENCENTREY = 32
REM THE POSITION OF OUR RECTANGLE
OBJPOSX = 0
OBJPOSY = 0
REM SCALE FACTOR FOR OUR RECTANGLE
OBJSCALE = 1.0
REM THE ROTATION ANGLE
OBJROTATION = 0.0
REM ENABLE GAMEPAD
GAMEPAD 1
REM INIT THE OBJECT THE FIRST TIME
OBJTYPE = OBJTYPERECTANGLE
GOSUB INITPOINTSANDEDGES
REM MAIN LOOP
DO
REM CLEAR SCREEN AND DRAW THE RECTANGLE
CLS
GOSUB CALCSCREENPOINTS
GOSUB DRAWEDGES
WAIT 0.04
REM WITHOUT ANY BUTTON PRESS WE MOVE THE RECTANGLE
IF UP(0) AND NOT BUTTON(0) THEN OBJPOSY = OBJPOSY - 1
IF DOWN(0) AND NOT BUTTON(0) THEN OBJPOSY = OBJPOSY + 1
IF LEFT(0) AND NOT BUTTON(0) THEN OBJPOSX = OBJPOSX - 1
IF RIGHT(0) AND NOT BUTTON(0) THEN OBJPOSX = OBJPOSX + 1
REM PRESSING BUTTON A AND UP OR DOWN CHANGES THE SCALE
IF DOWN(0) AND BUTTON(0) AND OBJSCALE > 0.1 THEN OBJSCALE = OBJSCALE - 0.1
IF UP(0) AND BUTTON(0) THEN OBJSCALE = OBJSCALE + 0.1
REM PRESSING BUTTON A AND LEFT OR RIGHT ROTATES THE OBJECT
IF LEFT(0) AND BUTTON(0, 1) THEN
REM TURN LEFT BY REDUCING OBJROTATION (AND THUS ROTATE COUNTERCLOCKWISE)
OBJROTATION = OBJROTATION - 0.1
REM IF WE PASS NORTH FROM THE RIGHT TO THE LEFT THEN WE NEED TO ADD 2 * PI
IF OBJROTATION < 0 THEN
OBJROTATION = OBJROTATION + 2 * PI
END IF
END IF
IF RIGHT(0) AND BUTTON(0, 1) THEN
REM TURN RIGHT BY INCREASING OBJROTATION (AND THUS ROTATE CLOCKWISE)
OBJROTATION = OBJROTATION + 0.1
REM IF WE PASS NORTH FROM THE LEFT TO THE RIGHT THEN WE NEED TO SUBSTRACT 2 * PI
IF OBJROTATION >= 2 * PI THEN
OBJROTATION = OBJROTATION - 2 * PI
END IF
END IF
REM IF BUTTON B IS PRESSED CHANGE OBJECT TO NEXT OBJECT TYPE
IF BUTTON(0, 2) THEN
OBJTYPE = OBJTYPE + 1
REM IF WE'RE OUT OF OBJECT TYPES RESTART AT THE RECTANGLE
IF OBJTYPE > OBJTYPEJET THEN
OBJTYPE = OBJTYPERECTANGLE
END IF
GOSUB INITPOINTSANDEDGES
END IF
LOOP
REM INIT POINTS AND EDGES
REM IN:
REM OBJTYPE: THE OBJECT TYPE TO BE READ
REM
INITPOINTSANDEDGES:
REM RESTORE TO THE RIGHT LABEL DEPENDING ON THE OBJECT TYPE
IF OBJTYPE = OBJTYPERECTANGLE THEN
RESTORE DATAOFRECTANGLE
ELSE IF OBJTYPE = OBJTYPETRIANGLE THEN
RESTORE DATAOFTRIANGLE
ELSE IF OBJTYPE = OBJTYPEJET THEN
RESTORE DATAOFJET
ELSE
PRINT "UNKNOWN OBJTYPE " + OBJTYPE
END
END IF
REM READ THE NUMBER OF POINTS FIRST
READ NUMBEROFPOINTS
REM THEN READ THE COORDINATES OF THE POINTS
FOR POINTNO = 0 TO NUMBEROFPOINTS - 1
READ POINTS(POINTNO, IDXX)
READ POINTS(POINTNO, IDXY)
NEXT POINTNO
REM NOW READ THE NUMBER OF EDGES
READ NUMBEROFEDGES
REM THEN READ THE START AND END POINT OF THE EDGES
FOR EDGENO = 0 TO NUMBEROFEDGES - 1
READ EDGES(EDGENO, IDXSTARTPOINT)
READ EDGES(EDGENO, IDXENDPOINT)
NEXT EDGENO
RETURN
CALCSCREENPOINTS:
FOR POINTNO = 0 TO NUMBEROFPOINTS - 1
SCREENPOINTS(POINTNO, IDXX) = COS(OBJROTATION) * POINTS(POINTNO, IDXX) - SIN(OBJROTATION) * POINTS(POINTNO, IDXY)
SCREENPOINTS(POINTNO, IDXY) = SIN(OBJROTATION) * POINTS(POINTNO, IDXX) + COS(OBJROTATION) * POINTS(POINTNO, IDXY)
SCREENPOINTS(POINTNO, IDXX) = SCREENPOINTS(POINTNO, IDXX) * OBJSCALE
SCREENPOINTS(POINTNO, IDXY) = SCREENPOINTS(POINTNO, IDXY) * OBJSCALE
SCREENPOINTS(POINTNO, IDXX) = SCREENPOINTS(POINTNO, IDXX) + OBJPOSX
SCREENPOINTS(POINTNO, IDXY) = SCREENPOINTS(POINTNO, IDXY) + OBJPOSY
SCREENPOINTS(POINTNO, IDXX) = SCREENPOINTS(POINTNO, IDXX) + SCREENCENTREX
SCREENPOINTS(POINTNO, IDXY) = SCREENPOINTS(POINTNO, IDXY) + SCREENCENTREY
SCREENPOINTS(POINTNO, IDXX) = INT(SCREENPOINTS(POINTNO, IDXX) + 0.5)
SCREENPOINTS(POINTNO, IDXY) = INT(SCREENPOINTS(POINTNO, IDXY) + 0.5)
NEXT POINTNO
RETURN
DRAWEDGES:
REM ITERATE OVER ALL EDGES
FOR EDGENO = 0 TO NUMBEROFEDGES - 1
STARTPOINT = EDGES(EDGENO, IDXSTARTPOINT)
ENDPOINT = EDGES(EDGENO, IDXENDPOINT)
REM DRAW FROM STARTPOINT TO ENDPOINT
LINE SCREENPOINTS(STARTPOINT, IDXX), SCREENPOINTS(STARTPOINT, IDXY) TO SCREENPOINTS(ENDPOINT, IDXX), SCREENPOINTS(ENDPOINT, IDXY)
NEXT EDGENO
RETURN
DATAOFRECTANGLE:
REM 4 POINTS FOLLOW
DATA 4
DATA -20, -10
DATA 20, -10
DATA 20, 10
DATA -20, 10
REM 4 EDGES FOLLOW
DATA 4
DATA 0, 1
DATA 1, 2
DATA 2, 3
DATA 3, 0
DATAOFTRIANGLE:
REM 3 POINTS FOLLOW
DATA 3
DATA 0, -10
DATA 10, 10
DATA -10, 10
REM 3 EDGES FOLLOW
DATA 3
DATA 0, 1
DATA 1, 2
DATA 2, 0
DATAOFJET:
REM 15 POINTS FOLLOW
DATA 15
DATA 0, -8
DATA 1, -5
DATA 1, -2
DATA 6, 3
DATA 1, 3
DATA 1, 6
DATA 3, 8
DATA 0, 8
DATA 0, 5
DATA -3, 8
DATA -1, 6
DATA -1, 3
DATA -6, 3
DATA -1, -2
DATA -1, -5
REM 18 EDGES FOLLOW
DATA 18
DATA 0,1
DATA 1,2
DATA 2,3
DATA 3,4
DATA 4,5
DATA 5,6
DATA 6,7
DATA 7,8
DATA 7,9
DATA 9,10
DATA 10,11
DATA 11,12
DATA 12,13
DATA 13,14
DATA 14,0
DATA 1,4
DATA 11,13
DATA 2,4
To be continued if I have time again and get some feedback 🙂