'=========================================================================== ' Subject: SIMULATION OF A SPIROGRAPH Date: 02-23-99 (21:53) ' Author: Nigel Traves Code: QB, QBasic, PDS ' Origin: tarot@ihalliwell.freeserve.co.u Packet: GRAPHICS.ABC '=========================================================================== 'SPIRO.BAS - A simulation of the most used part of the toy called a ' spirograph. Public domain. Use entirely at own risk. The ' author accepts no liability whatsoever. In the case that I have ' used a registered trademark, I apologise. I do not at this time ' own any trademarks. ' ' There is a toy called a spirograph that is used to make curved patterns. ' This toy consists of a number of pieces that are made from transparent ' plastic and a number of ball-point pens with different coloured inks in them. ' Each piece has gear-teeth along their outside edges. The gear-teeth are ' all of the same size, independant of the piece that they are on. In ' addition each piece has a number of holes in them, which are designed to ' accept a pen point. ' ' This program works in VGA mode 12 graphics and is a simulation of the most ' often used part of that toy. It simulates the use of 2 of the plastic pieces ' to produce a circular pattern. As this program uses double-precision ' numbers and maths, it is comparatively slow. One thing that I have done to ' speed this up is to have 2 identical SUBs with STATIC variables in them. ' This works by ensuring that the built-in functions SIN and COS are only ' called once for each of the 2 angles that are used. ' ' RULES ' ' In order to use this program there are a few rules that you should be aware ' of. DO NOT alter the value of the constant LargeDiameter#. DO NOT place a ' value in the constant SmallDiameter# that is less than or equal to zero or ' greater than or equal to the value in LargeDiameter#. DO NOT place a value ' greater than one or less than or equal to zero in the constant Offset. ' Violation of any of these rules will result in at best, the program ' attempting to draw off of the screen. ' ' Using this program. ' ' To experiment with the patterns that this program can produce it is only ' necessary to alter the values held in two constants. These constants are ' SmallDiameter# and Offset#. Changing the value in SmallDiameter# will alter ' the overall shape of the pattern while altering Offset# will change the ' "pointyness" of the peaks. To see what I am talking about, simply play ' around with these constants. Note that it is not necessary to change both ' values every time that you wish to change the pattern. ' ' Anyway, have fun. ' ' Nigel Traves - 11/1998 ' DECLARE SUB Orbit1 (PointX#, PointY#, OrbitX#, OrbitY#, Angle#, FirstTime%) DECLARE SUB Orbit2 (PointX#, PointY#, OrbitX#, OrbitY#, Angle#, FirstTime%) CONST PI# = 3.141592653589793# CONST LargeDiameter# = 478 CONST SmallDiameter# = 333 CONST CenterX# = 320, CenterY# = 240 CONST Offset# = .725 CONST Angle1# = 1 CONST StartColour = 1 CONST EndColour = 13 CONST FALSE% = 0 CONST TRUE% = NOT FALSE% LC# = (PI# * LargeDiameter#) / 360 A2# = 360 / ((PI# * SmallDiameter#) / LC#) SmallRadius# = SmallDiameter# / 2 SmallCenterY# = 1 + SmallRadius# SmallCenterX# = CenterX# StartX# = CenterX# StartY# = 1 + SmallRadius# - (SmallRadius# * Offset#) MyX# = StartX# MyY# = StartY# Orbit1 SmallCenterX#, SmallCenterY#, CenterX#, CenterY#, Angle1#, TRUE% Orbit1 MyX#, MyY#, CenterX#, CenterY#, Angle1#, FALSE% Orbit2 MyX#, MyY#, SmallCenterX#, SmallCenterY#, -A2#, TRUE% SCREEN 12 LINE (1, 1)-(640, 480), 15, BF Colour = StartColour LINE (StartX#, StartY#)-(MyX#, MyY#), Colour DO FOR Index% = 1 TO 360 Orbit1 SmallCenterX#, SmallCenterY#, CenterX#, CenterY#, Angle1#, FALSE% Orbit1 MyX#, MyY#, CenterX#, CenterY#, Angle1#, FALSE% Orbit2 MyX#, MyY#, SmallCenterX#, SmallCenterY#, -A2#, FALSE% LINE -(MyX#, MyY#), Colour IF INKEY$ <> "" THEN EXIT DO END IF NEXT Index% Colour = Colour + 1 IF Colour > EndColour THEN Colour = StartColour LOOP END SUB Orbit1 (PointX#, PointY#, OrbitX#, OrbitY#, Angle#, FirstTime%) STATIC C#, S# IF FirstTime% THEN C# = COS(Angle# * (PI# / 180#)) S# = SIN(Angle# * (PI# / 180#)) END IF OldX# = PointX# - OrbitX# OldY# = PointY# - OrbitY# PointX# = (OldX# * C# - OldY# * S#) + OrbitX# PointY# = (OldX# * S# + OldY# * C#) + OrbitY# END SUB SUB Orbit2 (PointX#, PointY#, OrbitX#, OrbitY#, Angle#, FirstTime%) STATIC C#, S# IF FirstTime% THEN C# = COS(Angle# * (PI# / 180#)) S# = SIN(Angle# * (PI# / 180#)) END IF OldX# = PointX# - OrbitX# OldY# = PointY# - OrbitY# PointX# = (OldX# * C# - OldY# * S#) + OrbitX# PointY# = (OldX# * S# + OldY# * C#) + OrbitY# END SUB