--- title: "Curve" id: 55005 type: "computer_media" slug: "curve" url: "http://localhost/computer_media/curve/" markdown_url: "http://localhost/computer_media/curve.md" published_at: "2024-06-10T07:03:30+00:00" modified_at: "2026-03-30T21:41:37+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2019/02/20230809-041332.jpg" excerpt: "An interactive Bézier curve designer lets you place up to 20 control points and watch the mathematically computed smooth curve plotted on screen." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "TS 2068" slug: "ts2068" taxonomy: "post_tag" url: "http://localhost/tag/ts2068/" model: - name: "Timex/Sinclair 2068" slug: "ts-2068" taxonomy: "model" url: "http://localhost/model/ts-2068/" genre: - name: "Demo" slug: "demo" taxonomy: "genre" url: "http://localhost/type/demo/" - name: "Graphics" slug: "graphics" taxonomy: "genre" url: "http://localhost/type/graphics/" media_contents: - id: 55021 title: "Long Island Sinclair Timex (LIST) User Group Library Tape #2" type: "computer_media" url: "http://localhost/computer_media/list-lib-2/" - id: 64711 title: "Long Island Sinclair Timex (LIST) User Group Library Tape #2.2" type: "computer_media" url: "http://localhost/computer_media/long-island-sinclair-timex-list-user-group-library-tape-2-2/" media_type: "Program" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2024/06/SCR-20260329-sbss.png" media_type_tags: "Demo, Graphics" --- This program draws Bézier curves on screen by accepting a series of control-point coordinates from the user and computing the curve using the Bernstein polynomial basis. Up to 20 corner (control) points are supported, stored in arrays x() and y(). The curve is evaluated at 50 evenly spaced parameter values (controlled by variable a=50), calculating blending coefficients iteratively in array b() to avoid expensive factorial computation. Users can optionally overlay the polygonal control frame before rendering the smooth curve, and a menu system lets them list, edit, store, or re-render the current set of control points. POKEs to addresses 23730–23731 adjust a system variable, likely setting the printer buffer or similar system parameter. *** ## Program Analysis ### Program Structure The program is organized around a top-level menu at line `40` that dispatches via a computed `GO TO (f*100)` at line `50`, routing to one of four sections based on user input: 1. Lines `100–190`: Input mode — collect control points and trigger curve computation. 2. Lines `200–320`: Alter mode — list, fix, or redraw control points (dispatched via `GO TO (200+h*30)`). 3. Lines `400`: Quit (STOP). 4. Lines `500–740`: Subroutines — curve computation (`510–640`), draw routine (`650–740`), and coordinate validation (`750–760`). A secondary menu at line `20` handles CLS, COPY (printer dump), or continuation, serving as a post-render hub before returning to the alter menu. ### Bézier Curve Algorithm The curve is computed using the Bernstein polynomial form of a Bézier curve. For `n+1` control points, parameter `j` steps from 0 to 1 across `a=50` sample points. The blending weights `b(i)` are built iteratively at line `560`: `b(i+1) = (g-i)/i * j/(1-j) * b(i)` This recurrence relation avoids computing binomial coefficients directly and is numerically efficient in BASIC. The anchor points are set explicitly: `c(1)=x(1)`, `d(1)=y(1)` and `c(a)=x(g)`, `d(a)=y(g)`, ensuring the curve passes exactly through the first and last control points. ### Key Variables | Variable | Purpose | | --- | --- | | `a` | Number of curve sample points (50) | | `g` | Total number of control points entered | | `n` | g−1 (degree of the Bézier curve) | | `x(i)`, `y(i)` | Control point coordinates (up to 20) | | `b(i)` | Bernstein blending weights at current parameter value | | `c(e)`, `d(e)` | Computed curve point coordinates | | `j` | Parameter value along the curve (0 to 1) | | `e` | Loop index across sample points | ### Notable Techniques - **Computed GO TO:** Both `GO TO (f*100)` at line `50` and `GO TO (200+h*30)` at line `220` act as jump tables, a common BASIC idiom for menu dispatch without long IF-THEN chains. - **Iterative Bernstein weights:** Rather than computing each binomial coefficient from scratch, the recurrence at line `560` builds the next weight from the previous, reducing computation significantly for higher-degree curves. - **Coordinate validation subroutine:** Lines `750–760` enforce screen bounds (x: 0–255, y: 0–175) via a loop with an INPUT prompt, preventing PLOT from receiving out-of-range values that would cause an error. - **Frame + curve toggle:** Lines `650–700` optionally draw the polygonal control hull using PLOT/DRAW before the sampled curve points are plotted, giving the user a visual reference for the control structure. - **INK 7 / INK 0 toggling:** Lines `290`, `300`, and `320` toggle ink color around `PLOT` calls using `USR 26727` and `USR 26715` — these USR calls with PLOT are suspicious and may be intended as machine code calls or are bugs resulting from a misuse of USR in a PLOT context. - **System variable POKEs:**`POKE 23730,30: POKE 23731,231` at line `10` writes to the ZX Spectrum system area (RASP/PIP area or similar), likely adjusting a system parameter at startup. ### Bugs and Anomalies - Lines `290`, `300`, and `320` use `PLOT 175,USR 26727` and `PLOT 175,USR 26715`. `USR` in this context calls a machine code routine and returns a value, so these PLOT statements would plot at coordinates derived from the machine code return value — almost certainly not the intended behavior. These lines may be remnants of an unfinished or ported section. - Line `200` dispatches with `GO TO (200+h*30)` for values 1–4, targeting lines `230`, `260`, `290`, and `320` respectively. However, the “old” option (h=3) lands at line `290` and the “both” option (h=4) at line `320`, both of which contain the suspicious PLOT/USR constructs noted above. - In the Bernstein weight loop (line `560`), if `j=1` (i.e., `1-j=0`), a division by zero would occur. This is avoided in practice because the loop runs from `e=2 TO a-1`, so `j` never actually reaches 1; the endpoints are set manually. - The `b()` array is dimensioned to 20 at line `10` but is indexed up to `n+1` (equal to `g`), so the limit of 20 control points is consistent with the array bounds. ## Source Code ``` 1 REM COPY BORDER !@ GO SUB VAL <> COPY @! BORDER GO SUB VAL <>x 10 LET a=50: DIM x(20): DIM y(20): DIM b(20): DIM c(100): DIM d(100): POKE 23730,30: POKE 23731,231: GO TO 40 20 INPUT "1)cls 2)copy 3)continue ";t: IF t=1 THEN CLS 30 IF t=2 THEN COPY 40 INK 0: INPUT "1)begin 2)alter 3)store 4)quit";f 50 GO TO (f*100) 100 INPUT "total number of corners: ";g 110 IF g>20 THEN INPUT "MUST be <=20...try again:";g: GO TO 110 120 LET n=g-1: INPUT "first coordinates: x=";x;" y=";y: GO SUB 750 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 170 GO SUB 750 180 NEXT i 190 GO SUB 510: GO TO 20 200 INPUT "1)list 2)fix 3)old 4)both 5)MM";h 210 IF h=5 THEN GO TO 20 220 GO TO (200+h*30) 230 CLS : PRINT "corner: (x) (y)" 240 FOR i=1 TO n+1: PRINT " ";i;")";TAB 10;x(i);TAB 17;y(i) 250 NEXT i: GO TO 200 260 INPUT "alter corner __? (0 if done)";i 270 IF i=0 THEN GO SUB 500: GO TO 200 280 INPUT "new coordinates: x=";x(i);" y=";y(i): GO TO 260 290 INK 7: PLOT 175,USR 26727: INK 0: GO TO 200 300 INK 7: PLOT 175,USR 26715: INK 0: GO TO 200 320 INK 7: PLOT 175,USR 26727: INK 0: GO SUB 650: GO TO 20 400 STOP 500 CLS 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 750 IF x<=255 AND x>=0 AND y<=175 AND y>=0 THEN RETURN 760 INPUT "HEY!...x<256,y<176! x=";x;" y=";y: GO TO 750 ```