This program draws all possible chord connections between every pair of vertices of a regular N-sided polygon (where N can range from 3 to 30), producing symmetrical star and web patterns on screen. The user inputs a value of N, and the program computes vertex positions using trigonometric functions on a unit circle, storing coordinates in arrays X() and Y(). A set of subroutines at lines 9400–9760 implement a simple virtual graphics pipeline: a coordinate-system origin setter, a moveto, and a lineto, all working through user-defined functions FN X and FN Y that map logical floating-point coordinates to physical pixel positions. The scaling logic at lines 9740–9750 ensures the drawing fits the screen by choosing the smaller of the horizontal and vertical scale factors, maintaining aspect ratio. After displaying the result for about six seconds, the program prompts for a new value of N and loops back to line 1 (a non-existent line, causing a clean restart to line 10).
Program Analysis
Program Structure
The program is divided into a main section (lines 10–300) and a library of subroutines occupying the high line-number range (9400–9760). This is a common Sinclair BASIC idiom for keeping utility routines well separated from program logic. The subroutines are well-commented with their inputs and outputs:
| Line Range | Subroutine | Purpose |
|---|---|---|
| 9400–9460 | lineto | PLOT current pen, DRAW to new point, update pen |
| 9500–9530 | moveto | Set pen position without drawing |
| 9600–9640 | setorigin | Shift logical origin and initialise pen |
| 9650–9660 | DEF FN X/Y | Map logical coords to screen pixels |
| 9700–9760 | start | Initialise display geometry and scale factors |
The subroutine addresses are stored in named variables (start, setorigin, moveto, lineto) at line 110, allowing GO SUB start etc. as readable calls — though on this platform the names are purely cosmetic since BASIC resolves them to values at runtime.
Geometry and Vertex Calculation
Vertices of the N-gon are placed on a unit circle. Starting at angle ALPHA=0, each successive vertex increments by ADIF = 2*PI/N radians (line 180). Coordinates are stored in X(I) and Y(I) arrays dimensioned to 30 elements (line 160). The nested loop at lines 230–280 iterates over all unique pairs (I,J) with I < J, connecting every vertex to every other — producing the complete graph KN drawn on the polygon.
Coordinate Mapping via DEF FN
Two user-defined functions at lines 9650–9660 handle the mapping from logical floating-point space to integer pixel coordinates:
FN X(Z) = INT((XORIG + Z) * XYSCALE + 0.5)FN Y(Z) = INT((YORIG + Z) * XYSCALE + 0.5)— note both useXYSCALE, not separate X and Y scales
The + 0.5 before INT implements rounding rather than truncation, ensuring pixel placement is as accurate as possible. Notably, both functions use XYSCALE (not YSCALE), which is intentional: the start subroutine selects the minimum of horizontal and vertical scale factors so the unit circle maps equally in both axes, preserving circularity.
Aspect Ratio and Scaling
Lines 9730–9750 compute the scale. The screen is defined as 256×176 pixels. Horizontal scale is NXPIX/HORIZ (256/3 ≈ 85.3) and vertical scale is NYPIX/VERT (176/2.1 ≈ 83.8). The smaller value (vertical, ~83.8) is chosen at line 9750 to avoid clipping. This value of VERT=2.1 is carefully chosen to produce a near-square pixel mapping given the screen’s non-square pixel aspect ratio.
Virtual Pen Model
The subroutines implement a simple pen-plotter abstraction. The pen position is maintained in XPEN and YPEN (in pixel coordinates). moveto sets the pen without drawing; lineto uses PLOT to the current pen position then DRAW the delta to the new position, updating the pen. This PLOT+DRAW idiom is standard for line drawing in Sinclair BASIC, as DRAW takes relative offsets rather than absolute endpoints.
Notable Techniques
- Subroutine entry points stored as numeric variables for readable
GO SUBcalls (line 110). - The loop at line 300 uses
GO TO 1— a non-existent line — causing execution to restart at line 10, a well-known Sinclair BASIC technique for a clean program restart withoutRUN. PAUSE 360(≈6 seconds at 60 Hz) followed by a keypress prompt andPAUSE 0is a standard display-then-wait idiom.- The origin is shifted by half the logical viewport dimensions (
XMOVE = HORIZ*0.5,YMOVE = VERT*0.5) so the unit circle is centred on screen.
Potential Anomalies
The variable YSCALE is computed at line 9740 but used only in the comparison at line 9750; it is never directly used in the coordinate mapping functions. This is by design — it exists solely to determine whether to clamp XYSCALE. The DIM X(30): DIM Y(30) at line 160 is inside the main loop path, meaning if the program is restarted via GO TO 1, these arrays will be re-dimensioned each run — which is harmless but slightly redundant.
Content
Source Code
10 REM "N-POLYGONS"
20 REM joining vertices of regular polygon with n-sides
30 REM Adapted by F. BOULDIN
40 BORDER 5: PAPER 7: INK 0
100 REM joining vertices of regular N-gon
110 CLS : LET start=9700: LET setorigin=9600: LET moveto=9500: LET lineto=9400
120 LET horiz=3: LET VERT=2.1
130 GO SUB start
140 LET XMOVE=HORIZ*0.5: LET YMOVE=VERT*0.5
150 GO SUB setorigin
160 DIM X(30): DIM Y(30)
169 REM setup vertices of regular N-gon in arrays X and Y
170 INPUT "TYPE VALUE OF N (3-30) ";N
180 LET ALPHA=0: LET ADIF=2*PI/N
190 FOR I=1 TO N
200 LET X(I)=COS ALPHA: LET Y(I)=SIN ALPHA
210 LET ALPHA=ALPHA+ADIF
220 NEXT I
229 REM join point I to point J:1<=I<J<=N
230 FOR I=1 TO N
240 FOR J=I+1 TO N
250 LET XPT=X(I): LET YPT=Y(I): GO SUB moveto
260 LET XPT=X(J): LET YPT=Y(J): GO SUB lineto
270 NEXT J
280 NEXT I
290 PAUSE 360: PRINT AT 21,1;" Press Any Key for New Start"
300 PAUSE 0: CLS : GO TO 1
9400 REM lineto
9401 REM IN:XPT,YPT,XPEN, YPEN
9402 REM OUT:XPEN, YPEN
9410 LET NXPEN=FN X(XPT)
9420 LET NYPEN=FN Y(YPT)
9430 PLOT XPEN,YPEN
9440 DRAW NXPEN-XPEN,NYPEN-YPEN
9450 LET XPEN=NXPEN: LET YPEN=NYPEN
9460 RETURN
9500 REM moveto
9501 REM IN:XPT,YPT
9502 REM OUT:XPEN, YPEN
9510 LET XPEN=FN X(XPT)
9520 LET YPEN=FN Y(YPT)
9530 RETURN
9600 REM setorigin
9601 REM IN:XORIG, YORIG, XMOVE, YMOVE
9602 REM OUT :XORIG, YORIG, XPEN, YPEN
9610 LET XORIG=XORIG+XMOVE: LET YORIG=YORIG+YMOVE
9620 LET XPEN=FN X(0)
9630 LET YPEN=FN Y(0)
9640 RETURN
9650 DEF FN X(Z)=INT ((XORIG+Z)*XYSCALE+0.5)
9660 DEF FN Y(Z)=INT ((YORIG+Z)*XYSCALE+0.5)
9700 REM start
9701 REM IN : HORIZ, VERT
9702 REM OUT : NXPIX, NYPIX, XORIG, YORIG, XYSCALE, XPEN, YPEN,
9710 LET XORIG = 0: LET YORIG = 0
9720 LET XPEN = 0: LET YPEN = 0
9730 LET NXPIX = 256: LET NYPIX = 176
9740 LET XYSCALE = NXPIX/HORIZ: LET YSCALE = NYPIX/VERT
9750 IF XYSCALE > YSCALE THEN LET XYSCALE = YSCALE
9760 RETURN
9999 SAVE "N-POLYGONS" LINE 1
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

