Monday, October 29, 2012

Petit Computer Journal #11


Trigonometry



Our last unfinished business about Math is now about to be concluded! It's pretty simple, really, so I'll add a few more things to round things up.

1. Map() we've seen this already

Let's begin by including an old function: MAP(). This is a function that lets you do numbers interpolation. It's a very useful subroutine, especially when dealing with graphics.

@MAP
Y2=(((X2-X1)/(X3-X1))*(Y3-Y1))+Y1
RETURN

2. LOR Left Or Right.

This is very useful in game making, as well as different programs requiring graphics and the ability to tell left from right. The idea behind it is very simple: You take the slope of a line, and compare it to the slope of the other line. That is: dy1/dx1 cmp dy2/dx2. With some algebraic manipulation, we get this:

@LOR
LOR=SGN((DY1*DX2)-(DY2*DX1))
RETURN

3. Angle Measurements and Rotation

We want the ability to tell heading. Fortunately, ATAN functions takes two variables, and returns the angle (in radian), so it is trivial to do so. To check the angle from center screen:

A=ATAN(TCHY-96,TCHX-128) :'ATAN(DY,DX)

For drawing the line from the center, we can have

DX=R*COS(A):DY=R*SIN(A)
GLINE 128,96,128+DX,96+DY

Where R is the radius desired. Change the value of R for shorter or longer line.

4. Perpendicular line + angle offset

By changing the value of A, we can have different offset angle. Here's if you want 90 degree angle or perpendicular line.


DX=R*COS(A+(PI()/2)):DY=R*SIN(A+(PI()/2))


5. Cone Whether or not a point is within a cone

Take a point (X,Y), and two lines. We can see whether or not the point lines inside the cone by taking the LOR values and compare them. You have to be mindful of the angle.

You can also check whether or not a point is inside triangle, by doing so:

TX=TCHX:TY=TCHY
TX1=128:TY1=30
TX2=18:TY2=135
TX3=228:TY3=100

GLINE TX1,TY1,TX2,TY2
GLINE TX2,TY2,TX3,TY3
GLINE TX3,TY3,TX1,TY1

@LOOP
TX=TCHX:TY=TCHY
DX1=TX2-TX1:DY1=TY2-TY1:DX2=TX-TX1:DY2=TY-TY1:GOSUB @LOR:LOR1=LOR
DX1=TX3-TX2:DY1=TY3-TY2:DX2=TX-TX2:DY2=TY-TY2:GOSUB @LOR:LOR2=LOR
DX1=TX1-TX3:DY1=TY1-TY3:DX2=TX-TX3:DY2=TY-TY3:GOSUB @LOR:LOR3=LOR

IF LOR1==LOR2 AND LOR2=LOR3 THEN GPAINT 128,96,4 ELSE GPAINT 128,96,6
GOTO @LOOP

6. Intersection between 2 lines

We can also use LOR to check intersection between to lines. If the points of line 1 is on opposite side of line 2 AND the points of line 2 is on opposite sites of line 1, then we have intersection.

@LOOP
ACLS

PX1=RND(256):PY1=RND(192)
PX2=RND(256):PY2=RND(192)
PX3=RND(256):PY3=RND(192)
PX4=RND(256):PY4=RND(192)

GLINE PX1,PY1,PX2,PY2,6
GLINE PX3,PY3,PX4,PY4,10

GOSUB @ISCROSS
IF ISCROSS THEN ?"INTERSECT"

LINPUT A$
GOTO @LOOP

@ISCROSS
ISCROSS=TRUE
DX1=PX2-PX1:DY1=PY2-PY1
DX2=PX3-PX1:DY2=PY3-PY1
GOSUB @LOR:LOR1=LOR
DX2=PX4-PX1:DY2=PY4-PY1
GOSUB @LOR:LOR=LOR
IF LOR1==LOR2 THEN ISCROSS=FALSE

DX1=PX4-PX3:DY1PY4-PY3
DX2=PX1-PX3:DY2=PY1-PY3
GOSUB @LOR:LOR1-LOR
DX2=PX2-PX3:DY2=PY2-PY3
GOSUB @LOR:LOR2=LOR
IF LOR1==LOR2 THEN ISCROSS=FALSE
RETURN

@LOR
LOR=SGN((DY1*DX2)-(DY2*DX1))
RETURN


7. Movement: Direction and Speed

Let's take a simple spaceship movement real quick. Actually, it can be a car, duck, or whatever.

ACLS
SPSET 0,256,0,0,0,0,16,8
SPHOME 0.8.4
SX=128:SY=96:'SHIP POSITION
SD=0:SS=0:'DIRECTION AND SPEED

@LOOP
VSYNC 1:GCLS:CLS

GOSUB @SETB
IF B$=="U" THEN SS=SS+1
IF B$=="D" THEN SS=SS-1
IF B$=="L" THEN SD=SD-3
IF B$=="R" THEN SD=SD+3

IF 0>SS THEN SS=0
SD=(SD+360)%360

DX=(SS/16)*COS(RAD(SD))
DY=(SS/16)*SIN(RAD(SD))

SX=(SX+DX+256)%256
SY=(SY+DY+192)192

SPANGLE 0,SD
SPOFS 0,SX,SY

GOTO @LOOP

@SETB
B=BUTTON(0):B$=""
IF B AND 1 THEN B$="U"
IF B AND 2 THEN B$="D"
IF B AND 4 THEN B$="L"
IF B AND 8 THEN B$="R"
RETURN

8. A simple game: Asteroid

Let's see if you can take what we have, and build a simple game of Asteroid.

ACLS
SPSET 0,136,0,0,0,0,16,16
SPHOME 0,8,8
SPCOL 0,0,0,8,8,FALSE,&H10
SPANGLE 0,270
SPOFS 0,128,96
SX=128:SY=96:'SHIP POSITION
VX=0:VY=0:'SHIP VELOCITY
SD=0:SS=0:'DIRECTION AND SPEED
BL=0
NX=-50:NY=-50
GOSUB @BSTART
GOSUB @RSTART
SCORE=0:SHOT=1:COL=0
MAXEN=50:TT=0
WAIT 30

@LOOP
LOCATE 0,0
?"HIT=";SCORE;"   SHOT=";SHOT;"   COL=";COL;"   "
?"ACC=";FLOOR(SCORE*100/SHOT);"   MAXEN=";MAXEN;"   "
VSYNC 1:'GCLS:CLS

B=BUTTON(0)
IF B AND 1 THEN SS=1 ELSE SS=0
IF B AND 2 THEN SS=0
IF B AND 4 THEN SD=SD-3
IF B AND 8 THEN SS=0
SD=(SD+360)%360
'IF B AND 16 THEN GOSUB @FIRE

DX=(SS/16)*COS(RAD(SD))
DY=(SS/16)*SIN(RAD(SD))

VX=(VX+DX)
VY=(VY+DY)
IF VX< -5 THEN VX=-5
IF VY< -5 THEN VY=-5
IF VX>5 THEN VX=5
IF VY>5 THEN VY=5

SX=(SX+VX+256)%256
SY=(SY+VY+192)%192
SPANGLE 0,SD
IF SPHIT(0)!=0 THEN COL=COL+1
IF B AND 16 THEN GOSUB @FIRE
GOSUB @BLT
GOSUB @RLT

CNT=CNT+1:IF CNT>1000 THEN CNT=1000
TT=TT+1
GOTO @LOOP

@RLT
FOR I=50 TO 99
IF I>MAXEN GOTO @RLT2
IF SPCHK(I)==8 THEN SPOFS I,RND(256),RND(192),RND(300)+100
@RLT2
NEXT
LOCATE 0,3:?"C=";C;"  "
IF C+50>MAXEN THEN MAXEN=MAXEN+1:C=0
RETURN

@BLT
LOCATE 20,0
FOR I=1 TO 20
IF SPCHK(I)==8 THEN SPOFS I,NX,NT
IF SPHIT(I)!=0 THEN GOSUB @HIT
NEXT
RETURN

@HIT
IF SPHITNO<=20 THEN RETURN
SPOFS SPHITNO,NX,NY
SPOFS SPHITNO,RND(512)-128,NY-30,700
SPOFS I,NX,NY
SPCHR SPHITNO,192+8*RND(4)
BEEP 13
SCORE=SCORE+1
C=C+1
RETURN

@BSTART
FOR BL=1 TO 20
SPSET BL,40,0,0,0,0,16,16
SPHOME BL,8,8
SPCOL BL,0,0,4,4,FALSE,&H01
SPANIM BL,2,10,0
SPANGLE BL,SD
SPOFS BL,NX,NT
NEXT
RETURN

@RSTART
FOR I=50 TO 99
SPSET I,200,RND(16),0,0,0,16,16
SPHOME I,8,8
SPCOL I,0,0,8,8,FALSE,&H11
SPANIM I,2,10,0
SPOFS I,299,265
NEXT
RETURN

@FIRE
IF CNT>5 THEN CNT=0 ELSE RETURN
BL=BL+1:IF BL>20 THEN BL=1
SPOFS BL,SX,SY
SPANGLE BL,SD
DX=300*COS(RAD(SD))
DY=300*SIN(RAD(SD))
SPOFS BL,SX+VX+DX,SY+VY+DY,100
BEEP 10
SHOT=SHOT+1
RETURN




No comments: