NPolygons

Developer(s): Frank Bouldin (W5GAA)
Date: 198x
Type: Program
Platform(s): TS 2068

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 RangeSubroutinePurpose
9400–9460linetoPLOT current pen, DRAW to new point, update pen
9500–9530movetoSet pen position without drawing
9600–9640setoriginShift logical origin and initialise pen
9650–9660DEF FN X/YMap logical coords to screen pixels
9700–9760startInitialise 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 use XYSCALE, 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 SUB calls (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 without RUN.
  • PAUSE 360 (≈6 seconds at 60 Hz) followed by a keypress prompt and PAUSE 0 is 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

Appears On

This tape is a compilation of programs from user group members (Robert Burton, David Baulch, Frank Bouldin, Chuck Dawson, Ryan
One of a series of library tapes. Programs on these tapes were renamed to a number series. This tape contained

Related Products

Related Articles

Related Content

Image Gallery

NPolygons

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.

Scroll to Top