--- title: "Random Plot" id: 56814 type: "computer_media" slug: "random-plot" url: "http://localhost/computer_media/random-plot/" markdown_url: "http://localhost/computer_media/random-plot.md" published_at: "2024-09-29T02:29:56+00:00" modified_at: "2026-04-03T07:58:51+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/09/304_RP.png" excerpt: "A pure-BASIC implementation of Bresenham's line algorithm draws 25 random lines across the screen — no machine code required, all eight octants handled correctly." 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 1000" slug: "ts1000" taxonomy: "post_tag" url: "http://localhost/tag/ts1000/" model: - name: "Timex/Sinclair 1000" slug: "ts-1000" taxonomy: "model" url: "http://localhost/model/ts-1000/" genre: - name: "Demo" slug: "demo" taxonomy: "genre" url: "http://localhost/type/demo/" media_contents: - id: 56738 title: "Timex Sinclair Public Domain Library Tape 1007" type: "computer_media" url: "http://localhost/computer_media/timex-sinclair-public-domain-library-tape-1007/" media_type: "Program" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2024/09/304_RP.png" media_type_tags: "Demo" --- This program draws 25 randomly placed straight lines on screen using Bresenham’s line-drawing algorithm implemented entirely in BASIC. Starting from a random point, it repeatedly selects a new random destination within a 62×42 pixel area and calls the subroutine at line 1000 to plot each line pixel by pixel. The subroutine correctly handles all octants by choosing the major axis (the longer dimension) as the driving axis and using an integer accumulator variable S to decide when to step along the minor axis. The REM statements scattered throughout appear to serve as inline documentation for intermediate values rather than functional code. *** ## Program Analysis ### Program Structure The program is divided into two parts: a short main loop (lines 10–70) and a line-drawing subroutine (lines 1000–1260). Lines 1270–1290 handle saving and re-running the program. 1. **Lines 10–20:** Initialise the starting point (`A`, `B`) with random coordinates. 2. **Lines 25–70:** Loop 25 times, each iteration picking a random endpoint (`C`, `D`), calling the line-draw subroutine, then advancing the current position to the endpoint. 3. **Lines 1000–1260:** Bresenham’s line-drawing subroutine, plotting from (`A`,`B`) to (`C`,`D`). ### Coordinate Space Random coordinates are constrained to a 62×42 pixel region: `A` and `C` are in the range 1–62 and `B` and `D` in the range 1–42. This keeps all points within the displayable screen area without risk of out-of-bounds PLOT errors. ### Bresenham’s Line Algorithm The subroutine at line 1000 is a faithful BASIC implementation of Bresenham’s integer line algorithm. Key variables are: | Variable | Role | | --- | --- | | `U` | Horizontal delta (C−A) | | `V` | Vertical delta (D−B) | | `D1X`, `D1Y` | Diagonal step direction (both axes) | | `D2X`, `D2Y` | Primary-axis step direction (one axis only) | | `M` | Length of the major (driving) axis | | `N` | Length of the minor axis | | `S` | Bresenham error accumulator, initialised to `INT(M/2)` | | `L` | Loop counter, 0 to M inclusive | The algorithm determines which axis is longer (lines 1060–1120) and sets the step vectors accordingly so that it always iterates along the major axis. At each step, `N` is added to the accumulator `S`; when `S` reaches or exceeds `M`, `M` is subtracted and a diagonal step (`D1X`, `D1Y`) is taken; otherwise only the primary-axis step (`D2X`, `D2Y`) is used. This correctly handles all eight octants. ### Notable Techniques - **SGN for direction:**`SGN U` and `SGN V` extract ±1 or 0 cleanly without any IF/THEN branching, keeping the step-vector setup compact. - **Error accumulator initialisation:** Setting `S = INT(M/2)` before the loop centres the error term, producing a more visually symmetric line than initialising to 0. - **Connected line segments:** After each subroutine call, `A` and `B` are updated to `C` and `D` (lines 50–60), so successive lines form a continuous polyline rather than isolated segments. - **REM as commentary:** Several REM statements (e.g. lines 1005, 1015, 1035) appear immediately after variable assignments to document what each variable represents, a common documentation practice in BASIC of this era. ### Bugs and Anomalies - **Subroutine modifies caller variables:** The subroutine uses `A` and `B` as its working plot position, overwriting the caller’s start-point values during the drawing loop. The main loop relies on this side-effect by reading the final values of `A` and `B` at lines 50–60 — however, because the loop always runs from 0 to `M` inclusive and ends exactly at (`C`, `D`), the final values of `A` and `B` after the RETURN will equal the original `C` and `D`, so the behaviour is correct if fragile. - **Line 1270 CLEAR:** This line is unreachable during normal execution (the RETURN at 1260 sends control back to the main loop, which ends at line 70 with no fall-through). It would only execute if the main loop somehow fell through, suggesting it may be a remnant of development. ## Source Code ``` 10 LET A=INT (RND*62)+1 20 LET B=INT (RND*42)+1 25 FOR P=1 TO 25 30 LET C=INT (RND*62)+1 40 LET D=INT (RND*42)+1 45 GOSUB 1000 50 LET A=C 60 LET B=D 70 NEXT P 1000 LET U=C-A 1005 REM U 1010 LET V=D-B 1015 REM V 1020 LET D1X=SGN U 1030 LET D1Y=SGN V 1035 REM (D1X,D1Y) 1040 LET D2X=SGN U 1050 LET D2Y=0 1055 REM (D2X,D2Y) 1060 LET M=ABS U 1070 LET N=ABS V 1080 IF M>N THEN GOTO 1130 1090 LET D2X=0 1100 LET D2Y=SGN V 1105 REM (D2X,D2Y) 1110 LET M=ABS V 1120 LET N=ABS U 1130 REM 1140 LET S=INT (M/2) 1145 REM 1150 FOR L=0 TO M 1160 PLOT A,B 1170 LET S=S+N 1180 IF S