Google
 

Trailing-Edge - PDP-10 Archives - decuslib10-12 - 43,50547/circle.mac
There is 1 other file named circle.mac in the archive. Click here to see a list.
	TITLE CIRCLE - ROUTINE TO PLOT CIRCLES, HAS OPTIONAL ARGUMENTS
	SUBTTL BY JOE SMITH, 16 AUG 76


	COMMENT	&
THIS IS A FORTRAN-10 CALLABLE ROUTINE TO PLOT CIRCLES.  3 ARGUMENTS ARE
REQUIRED, UP TO 9 MAY BE SPECIFIED.

EXAMPLES

CALL CIRCLE (X0, Y0, RAD)
	X0 AND Y0 ARE THE COORDINATES OF THE CENTER (IN INCHES), RAD IS THE RADIUS

CALL CIRCLE (X0, Y0, RAD, ANG)
	DRAWS A SEMICIRCLE WITH RADIUS RAD, CENTER (X0,Y0), STARTING AT ANGLE
	ANG AND GOING COUNTERCLOCKWISE 180 DEGREES.  ANG IS THE ANGLE IN DEGREES
	MEASURED COUNTERCLOCKWISE FROM THE X-AXIS.

CALL CIRCLE (X0, Y0, RAD, ANG1, ANG2)
	DRAWS A CIRCULAR ARC FROM ANGLE ANG1 TO ANGLE ANG2.

CALL CIRCLE (X0, Y0, RAD1, ANG1, ANG2, RAD2)
	DRAWS A SPIRAL STARTING AT (RAD1,ANG1) AND GOING TO (RAD2,ANG2) RELATIVE
	TO THE "CENTER" (X0,Y0).  IF ANG1=ANG2, A STRAIGHT LINE WILL BE DRAWN
	FROM RAD1 TO RAD2 ALONG THE SPECIFIED ANGLE AND RELATIVE TO (X0,Y0).

CALL CIRCLE (X0, Y0, RAD1, ANG1, ANG2, RAD2, DASH)
	DRAWS A DASHED CIRCLE (OR SPIRAL).  DASH IS THE DISTANCE (IN INCHES)
	FOR THE PEN TO BE UP OR DOWN.

CALL CIRCLE (X0, Y0, RAD1, ANG1, ANG2, RAD2, DOWN, UP)
	DRAWS A DASHED CIRCLE (OR SPIRAL).  DOWN AND UP ARE IN INCHES.
	DOWN IS THE DISTANCE THAT THE PEN WILL BE DOWN AND UP IS THE DISTANCE
	FOR THE PEN TO BE UP.

CALL CIRCLE (X0, Y0, RAD1, ANG1, ANG2, RAD2, DOWN, UP, STEP)
	STEP IS THE SIZE OF THE STEPS USED IN APPROXIMATING THE CIRCLE.
	THE DEFAULT SIZE IS 5.0 DEGREES (72 STEPS).  THE MAGNITUDE OF STEP
	IS USED, 0 MEANS USE THE DEFAULT SIZE (5.0 DEGREES)

	IF X0 OR Y0 ARE 999.0, THE CURRENT PEN POSITION WILL BE USED FOR
	THE RESPECTIVE	COORDINATE.

CALL CIRCLE (X0, Y0, 0.0, ANGLE, ANGLE, 1.0)
CALL CIRCLE (999.0, 999.0, 0.1, ANGLE+90.0, ANGLE+90.0, 0.0)
	WILL PLOT A ONE INCH LINE AT THE SPECIFIED ANGLE AND A TENTH 
	INCH LINE PERPENDICULAR TO THE END

THIS SUBROUTINE CALLS DASH2 (XSTART, YSTART, XEND, YEND, DOWN, UP)

***********		Original FORTRAN subroutine		*************

	SUBROUTINE CIRCLE (X0, Y0, START, STOP, STEP, R1, R2, DOWN, UP)
	IF (X0 .GT. 999.0)  X0=X
	IF (Y0 .GT. 999.0)  Y0=Y
	IF (STEP .EQ. 0.0  .OR.  DOWN .LE. 0.0)  RETURN
	XSTART=COSD (START) * R1 + X0
	YSTART=SIND (START) * R1 + Y0
	IF (START .EQ. STOP)  GOTO 20
	CALL DASH2 (XSTART, YSTART, XSTART, YSTART, 0.0, UP)
	DIFF=(R2-R1) / (STOP-START)
	DO 10 DEGREE=START+STEP, STOP+STEP/2.0, STEP
	RADIUS=R1 + DIFF*(DEGREE-START)
	X=COSD (DEGREE) * RADIUS + X0
	Y=SIND (DEGREE) * RADIUS + Y0
10	CALL DASH2 (1000.0, 1000.0, X, Y, DOWN, UP)
	RETURN
20	X=COSD (STOP) * R2 + X0
	Y=SIND (STOP) * R2 + Y0
	CALL DASH2 (XSTART, YSTART, X, Y, DOWN, UP)
	RETURN
	END

&	;End of COMMENT
	SUBTTL	FIRST 3 ARGS

	AC0=0
	TEMP=AC0+1
	DEG=TEMP+1
	RAD=DEG+1
	SIN=RAD+1
	COS=SIN+1
	L=16				;LINK TO FORTRAN ARGUMENTS
	P=17				;FORTRAN PUSH DOWN LIST
	SIZE=5.0	;DEFAULT STEP SIZE, MUST BE POSITIVE FLOATING POINT

	ENTRY CIRCLE
	EXTERN COSD., SIND., DASH2, WHERE

	SIXBIT	/CIRCLE/		;FOR SUBROUTINE TRACE
CIRCLE:	MOVEM	L,.CIR16		;SAVE ORIGINAL LINK
	MOVEI	L,WHER			;FIND OUT WHERE WE ARE
	PUSHJ	P,WHERE			;ANSWERS IN XEND, YEND

	MOVE	L,.CIR16		;GET BACK THE LINK
	MOVE	TEMP,@0(L)		;GET X ORGIN
	CAMN	TEMP,NINE99		;IS IT EQUAL TO 999.0
	 MOVE	TEMP,XEND		;YES, USE OLD VALUE
	MOVEM	TEMP,XORIG		;STORE X ORIGIN

	MOVE	TEMP,@1(L)		;GET Y ORGIN
	CAMN	TEMP,NINE99		;IS IT EQUAL TO 999.0
	 MOVE	TEMP,YEND		;YES, USE OLD VALUE
	MOVEM	TEMP,YORIG		;STORE Y ORIGIN

	MOVE	RAD,@2(L)		;GET STARTING RADIUS
	MOVEM	RAD,RADIUS		;AND STORE IT

	MOVSI	TEMP,(SIZE)		;GET THE DEFAULT SIZE
	MOVEM	TEMP,STEP		;STORE STEP SIZE
	MOVEM	TEMP,DOWN		;START WITH PEN DOWN
	SETZB	DEG,UP			;START AT 0 DEGREES, PEN NOT UP
	MOVSI	SIN,(360.0)		;360.0 DEGREES
	MOVEM	SIN,ANG2		;TO GO FULL CIRCLE

	HLRZ	TEMP,-1(L)		;GET NUMBER OF ARGUMENTS
	CAIL	TEMP,-^D9		;MAX OF 9 ARGS
	 JRST	@NUMARG(TEMP)		;DEPENDING ON NUMBER OF ARGS
	JRST	ARG9
	ARG9
	ARG8
	ARG7
	ARG6
	ARG5
	ARG4
	ARG3
	RETURN				;ONLY 2 ARGS
	RETURN				;ONLY 1 ARG
NUMARG:	RETURN				;REFUSE TO DO ANYTHING
	SUBTTL	PICK UP OPTIONAL ARGUMENTS

ARG9:	MOVM	TEMP,@8(L)		;GET MAGNITUDE OF STEP SIZE
	SKIPE	TEMP			;USE DEFAULT IF ZERO
	 MOVEM	TEMP,STEP		;NONZERO, USE IT

ARG8:	MOVE	TEMP,@7(L)		;GET DISTANCE FOR PEN UP
	MOVEM	TEMP,UP			;AND STORE IT
	MOVE	TEMP,@6(L)		;GET DISTANGE FOR PEN DOWN
	MOVEM	TEMP,DOWN		;AND STORE IT
	JRST	ARG6

ARG7:	MOVE	TEMP,@6(L)		;GET DISTANCE FOR PEN DOWN
	MOVEM	TEMP,DOWN		;AND STORE IT
	MOVEM	TEMP,UP			;AS UP DISTANCE ALSO

ARG6:	MOVE	RAD,@5(L)		;GET ENDING RADIUS
	EXCH	RAD,RADIUS		;AND STORE IT

ARG5:	MOVE	TEMP,@4(L)		;GET ENDING ANGLE
	MOVEM	TEMP,ANG2		;AND STORE IT
	MOVE	DEG,@3(L)		;GET STARTING ANGLE
	JRST	ARG3

ARG4:	MOVE	DEG,@3(L)		;GET STARTING ANGLE
	FSC	SIN,-1			;DIVIDE 360 BY 2
	FADR	SIN,DEG			;ADD TO THE STARTING ANGLE
	MOVEM	SIN,ANG2		;STORE AS ENDING ANGLE

	;ALL ARGUMENTS HAVE BEEN DEFINED

ARG3:	MOVEM	DEG,DEGREE		;SET TO STARTING ANGLE
	MOVEI	L,TRIG			;LINK TO ARG
	PUSHJ	P,COSD.			;FIND COSINE OF ANGLE
	MOVEM	AC0,COS			;SAVE THE COSINE
	FMPR	AC0,RAD			;MULTIPLY BY STARTING RADIUS
	FADR	AC0,XORIG		;ADD XORIG
	MOVEM	AC0,XSTART		;SAVE IN XSTART

	PUSHJ	P,SIND.			;SINE, SAME ANGLE
	MOVEM	AC0,SIN			;SAVE THE SINE
	FMPR	AC0,RAD			;MULTIPLY BY RADIUS
	FADR	AC0,YORIG		;ADD YORIG
	MOVEM	AC0,YSTART		;SAVE IN YSTART
	FSBR	DEG,ANG2		;FIND THE DIFFERENCE BETWEEN ANGLES
	JUMPE	DEG,LINE		;THE SAME, DRAW STRAIGHT LINE
	SUBTTL	DRAW CIRCLE

	SKIPL	DEG			;SEE IF WE GO CLOCKWISE
	 MOVNS	STEP			;YES, NEGATE STEP SIZE
	FSBR	RAD,RADIUS		;SUBTRACT ENDING RADIUS FROM STARTING
	FDVR	RAD,DEG			;DIVIDE THE TWO
	MOVEM	RAD,RATIO		;STORE THE RATIO
	JRST	LOOP0			;START CIRCLE

;SUBROUTINES DESTROY THE AC'S, SO ALL PERTAINANT VALUES ARE STORED IN MEMORY
LOOP:	MOVE	TEMP,NINE99		;TELL DASH2 TO USE OLD POSITION
	MOVEM	TEMP,XSTART		;STORE AS OLD POSITION
	MOVEM	TEMP,YSTART

LOOP0:	MOVE	DEG,STEP		;GET STEP SIZE
	FADRB	DEG,DEGREE		;BUMP DEGREE
	FSBR	DEG,ANG2		;HOW MUCH MORE TO DO ?
	MOVE	RAD,DEG			;TO COMPUTE RADIUS
	FADR	DEG,STEP		;IN CASE WE ARE WITHIN ONE STEP
	XOR	DEG,STEP		;EXCLUSIVE OR THE SIGN BITS
	JUMPGE	DEG,LAST		;IF STEP AND DEG HAD SAME SIGN
	FMPR	RAD,RATIO		;MULTIPLY BY THE RATIO
	FADR	RAD,RADIUS		;ADD THE ENDING RADIUS

	MOVEI	L,TRIG			;LINK TO THE DEGREES AGRUMENT
	PUSHJ	P,COSD.			;FIND THE COSINE
	FMPR	AC0,RAD			;MULTIPLY BY CURRENT RADIUS
	FADR	AC0,XORIG		;ADD THE X ORIGIN
	MOVEM	AC0,XEND		;SAVE RESULT FOR DASH2

	PUSHJ	P,SIND.			;FIND SINE OF SAME ANGLE
	FMPR	AC0,RAD			;MULTIPLY BY RADIUS
	FADR	AC0,YORIG		;ADD IN THE Y ORGIN
	MOVEM	AC0,YEND		;AND SAVE

	MOVEI	L,DASARG		;LINK TO DASH2 ARGUEMENTS
	PUSHJ	P,DASH2			;PLOT THIS LINE SEGMENT
	JRST	LOOP			;GO BACK FOR MORE
	SUBTTL	LAST MOVE

LAST:	MOVE	DEG,ANG2		;GET THE FINAL ANGLE
	MOVEM	DEG,DEGREE		;STORE IT
	MOVEI	L,TRIG			;LINK TO TRIG FUNCTIONS
	PUSHJ	P,COSD.			;FIND THE COSINE
	MOVEM	AC0,COS			;KEEP IT
	PUSHJ	P,SIND.			;SINE, SAME ANGLE
	MOVEM	AC0,SIN			;KEEP IT
					;FALL INTO LINE

	;LINE - FOR PLOTTING A STRAIGHT LINE AT SPECIFIED ANGLE
	;FROM RAD1 TO RAD2 RELATIVE TO (XORIG,YORIG)

LINE:	FMPR	COS,RADIUS		;MULTIPLY COSINE TIMES ENDING RADIUS
	FADR	COS,XORIG		;ADD X ORIGIN
	MOVEM	COS,XEND		;SO DASH2 CAN FIND IT
	FMPR	SIN,RADIUS		;MULTIPLY SINE TIMES RADIUS
	FADR	SIN,YORIG		;ADD THE Y ORIGIN
	MOVEM	SIN,YEND		;SAVE IT
	MOVEI	L,DASARG		;LINK TO ARG LIST FOR DASH2
	PUSHJ	P,DASH2			;PLOT LINE
					;FALL INTO RETURN


RETURN:	MOVE	L,.CIR16		;RESTORE OLD LINK
	POPJ	P,			;AND RETURN
;ALL ARGUMENTS ARE RETURNED UNCHANGED
	SUBTTL	WORK STORAGE AREA

	;ARGUMENT BLOCKS:

	-3,,0
WHER:	200,,XEND		;FOR WHERE
	200,,YEND
	200,,UP			;VALUE IS NOT USED

	-1,,0
TRIG:	200,,DEGREE			;FOR COSD. AND SIND.


	-6,,0
DASARG:	200,,XSTART			;FOR DASH2
	200,,YSTART
	200,,XEND
	200,,YEND
	200,,DOWN
	200,,UP

NINE99:	999.0				;OLD VALUE

	;VARIABLES

	INTEGER .CIR16, XEND, XORIG, YEND, YORIG, RADIUS
	INTEGER STEP, UP, DOWN, ANG2, DEGREE, RATIO, XSTART, YSTART


	END