Curve 2

This file is part of and Long Island Sinclair Timex (LIST) User Group Library Tape #2. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 2068
Tags: Demo, Graphics

This program draws Bézier curves through a user-defined set of control points on the screen. The user inputs the number of corners and their X/Y coordinates; the subroutine at line 510 then computes 60 points along a degree-(n) Bernstein polynomial curve using the standard binomial-coefficient recurrence relation. The program optionally overlays the control polygon (the “frame”) on top of the curve. Arrays C and D store the 120-element X and Y coordinate buffers for the computed curve points, which are then plotted individually rather than connected with DRAW commands.


Program Analysis

Program Structure

The program is divided into two functional parts: an input and setup section (lines 1–190) and a curve-computation/rendering subroutine (lines 510–740). Line 400’s STOP acts as a guard between the main code and the subroutine, preventing fall-through. The subroutine is called via GO SUB 510 at line 190 and returns at line 740.

  1. Lines 1–10: REM header and variable/array initialization. a=60 sets the number of curve sample points. Arrays x(20) and y(20) hold control point coordinates; b(20) holds Bernstein basis values; c(120) and d(120) hold computed curve X/Y positions.
  2. Lines 100–180: User input loop — prompts for the total number of corners g, then iterates to collect each control point, plotting each as it is entered.
  3. Lines 510–740: Bézier curve computation and rendering subroutine.

Mathematical Technique: Bernstein Basis Recurrence

The subroutine implements an nth-degree Bézier curve (where n = g − 1) using the Bernstein polynomial basis. Rather than computing binomial coefficients directly, it uses the recurrence relation at line 560:

b(i+1) = (g-i)/i * j/(1-j) * b(i)

This is a standard multiplicative recurrence for the ratio of successive binomial terms, scaled by the parameter ratio j/(1-j). The seed value b(1) = (1-j)^n at line 550 is the first Bernstein basis polynomial B(0,n). This approach avoids computing factorials or large integers, making it numerically efficient for BASIC.

The parameter j runs from 0 to 1 across a=60 steps (lines 530–540), and the curve points are accumulated as weighted sums of the control points (lines 590–620).

Array Sizing and Constraints

ArraySizePurpose
x(20), y(20)20Control point coordinates (max 20 corners)
b(20)20Bernstein basis values per sample step
c(120), d(120)120Computed curve point coordinates

The curve arrays are sized at 120 but only 60 entries (indices 1 to a=60) are used. This is a conservative over-allocation; halving the array sizes to 60 would save memory without affecting correctness.

Rendering

After computing the curve, the user is prompted at line 650 to choose between curve-only (c) or frame and curve (f). The control polygon is drawn using PLOT/DRAW pairs at lines 680–700. The curve itself is rendered by individually PLOTting each precomputed point at lines 710–730 — no DRAW is used between curve points, so the curve appears as a series of discrete dots rather than connected line segments.

Notable Techniques and Idioms

  • The boundary points are set directly: c(1)=x(1), d(1)=y(1) (line 510) and c(a)=x(g), d(a)=y(g) (line 640), ensuring the curve passes exactly through the first and last control points without relying on floating-point evaluation at j=0 or j=1 (which would cause a divide-by-zero in the recurrence at j=1).
  • The loop at line 530 runs from e=2 TO a-1, deliberately skipping the endpoints already set — a clean guard against the singularity at j=1 where 1-j=0 would cause a division error.
  • Input for the first point at line 120 uses a dual-variable INPUT statement, then copies values into the array inside the loop (line 140), reusing a single pass for both first and subsequent points.

Bugs and Anomalies

  • The input comparison at line 660 checks for lowercase "c" only. If the user types uppercase C, the condition fails and the frame is drawn regardless of intent. Similarly, any input other than lowercase c will trigger frame drawing, meaning the F/f distinction in the prompt is cosmetic — only c is actually tested.
  • The curve is plotted as isolated pixels (line 720 uses PLOT only), so at low curvature or large screen distances between sample points, gaps may appear in the rendered curve.
  • There is no bounds check on g; entering more than 20 corners would cause a subscript error when accessing x(i) or y(i).

Content

Appears On

Track the OSCAR 10 satellite, design Bézier curves interactively, take a geography quiz on a hand-drawn map of North America, or hear the Olympic fanfare — LIST Library Tape 2 is a well-curated selection of practical and creative programs.

Related Products

Related Articles

Related Content

Image Gallery

Source Code

    1 REM      curve program             
   10 LET a=60: DIM x(20): DIM y(20): DIM b(20): DIM c(120): DIM d(120)
  100 INPUT "total number of corners:  ";g
  110 LET n=g-1
  120 INPUT "first coordinates: x=";x;" y=";y
  130 FOR i=1 TO n+1
  140 LET x(i)=x: LET y(i)=y
  150 PLOT x,y: IF i=n+1 THEN GO TO 180
  160 INPUT "next coordinates: x=";x;" y=";y
  180 NEXT i
  190 GO SUB 510
  400 STOP 
  510 LET c(1)=x(1): LET d(1)=y(1)
  530 FOR e=2 TO a-1
  540 LET j=((e-1))/(a-1): LET b(1)=(1-j)^n
  550 FOR i=1 TO n
  560 LET b(i+1)=(g-i)/i*j/(1-j)*b(i)
  570 NEXT i
  580 LET c(e)=0: LET d(e)=0
  590 FOR i=1 TO n+1
  600 LET c(e)=c(e)+b(i)*x(i)
  610 LET d(e)=d(e)+b(i)*y(i)
  620 NEXT i
  630 NEXT e
  640 LET c(a)=x(g): LET d(a)=y(g)
  650 INPUT "C)curve only F)frame & curve";z$
  660 IF z$="c" THEN GO TO 710
  670 FOR i=1 TO n
  680 PLOT x(i),y(i)
  690 DRAW x(i+1)-x(i),y(i+1)-y(i)
  700 NEXT i
  710 FOR e=2 TO a-1
  720 PLOT c(e),d(e)
  730 NEXT e
  740 RETURN 

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

People

No people associated with this content.

Scroll to Top