You are not logged in or registered. Please login or register to use the full functionality of this board...
SIGN IN Join Our Community For FREE


QB64 Spirograph's by TJP
07-04-2017, 09:19 PM (This post was last modified: 07-05-2017 02:10 AM by Waltersmind.)
Post: #1
 (Print Post)
QB64 Spirograph's by TJP
Due to the latest craze of spirographs on this forum and others, I decided to take a moment and create a more realistic demo in QB64.

Here are several screenshots of the Spirograph demo:

                   

While this demo could have more features, I wanted to share this to the community as soon as possible. What this demo does have this point is the ability to increase as well as decrease the size of both the hollow gear, and the solid gear. You can change the pen color as well as the thickness of the pen. The other cool feature, is you can move the pen hole up and down on the solid gear to change the pattern drawn.

All of those features are done in real time.

Here is the source code to the demo. Please note, I commented a few areas, but not many. However you should be able to determine what is going on by the names of the variables.

Code Snippet: [Select]
CONST TRUE = -1
CONST FALSE = 0

DIM ToothSize AS _FLOAT
DIM Circumference AS _FLOAT
DIM Radius AS _FLOAT
DIM ArcDegrees AS _FLOAT
DIM ArcDegreesHalf AS _FLOAT
DIM CutDepth AS _FLOAT
DIM CutRadius AS _FLOAT
DIM CenterX AS _UNSIGNED INTEGER
DIM CenterY AS _UNSIGNED INTEGER
DIM Scale AS _FLOAT
DIM NumberOfArcs AS _FLOAT
DIM NumberOfTeethHollowGearInside AS _UNSIGNED LONG
DIM NumberOfTeethHollowGearOutside AS _UNSIGNED LONG
DIM NumberOfTeethSolidGear AS _UNSIGNED LONG

DIM SolidGearOffsetRadius AS _FLOAT
DIM SolidGearAnglePosition AS _FLOAT
DIM SolidGearAngleRotation AS _FLOAT
DIM SolidGearPenHoleRadius AS _FLOAT
DIM SolidGearOffsetX AS _FLOAT
DIM SolidGearOffsetXOld AS _FLOAT
DIM SolidGearOffsetY AS _FLOAT
DIM SolidGearOffsetYOld AS _FLOAT

'  DEFINE IMAGES USED IN DEMO
DIM HollowGear AS LONG
DIM SolidGear AS LONG
DIM DrawingPaper AS LONG
DIM HelpMenu AS LONG

DIM SHARED Degree AS _FLOAT

DIM PenColor AS _UNSIGNED LONG
DIM PenSize AS _UNSIGNED INTEGER
DIM DrawingSpeed AS _UNSIGNED INTEGER

DIM PenOn AS _BYTE
DIM SolidGearMoving AS _BYTE
DIM SolidGearMinTeeth AS _UNSIGNED INTEGER
DIM HollowGearMinTeeth AS _UNSIGNED INTEGER
DIM PenSizeMin AS _UNSIGNED INTEGER
DIM SolidGearSpeed AS INTEGER
DIM PenHoleDistancePercent AS _FLOAT

PenOn = FALSE
SolidGearMoving = FALSE
SolidGearMinTeeth = 14
HollowGearMinTeeth = 24
PenSizeMin = 1
SolidGearSpeed = 1

PenColor = _RGB32(255, 255, 0)
PenSize = PenSizeMin
DrawingSpeed = 1

ToothSize = 3 / 32 '  SIZE IS IN INCHES
Degree = _PI / 180
Scale = 100
CutDepth = (1 / 16) * Scale '  SIZE IN INCHES

SCREEN _NEWIMAGE(800, 600, 32)
_TITLE "The Joyful Programmer - Spirograph's Ver 01"

CenterX = _WIDTH(0) / 2
CenterY = _HEIGHT(0) / 2


'  *** CREATE HELP MENU ***

HelpMenu = _NEWIMAGE(270, 260, 32)
_DEST HelpMenu

LINE (0, 0)-(_WIDTH(HelpMenu) - 1, _HEIGHT(HelpMenu) - 1), _RGB32(160, 160, 160), BF
LINE (5, 5)-(_WIDTH(HelpMenu) - 6, _HEIGHT(HelpMenu) - 6), _RGB32(250, 250, 250), BF

_SETALPHA 64, _RGB32(160, 160, 160)
_SETALPHA 64, _RGB32(250, 250, 250)

COLOR _RGB32(0, 0, 200)
_PRINTMODE _KEEPBACKGROUND
_PRINTSTRING (8, 8), "COMMAND KEYS:"

COLOR _RGB32(0, 160, 0)
_PRINTSTRING (10, 30), "1 = Pen DOWN/UP"
_PRINTSTRING (10, 46), "2 = Solid Gear Spin ON/OFF"
_PRINTSTRING (10, 62), "3 = Pen Size INCREASE"
_PRINTSTRING (10, 78), "4 = Pen Size DECREASE"
_PRINTSTRING (10, 94), "5 = CLEAR DRAWING PAPER"
_PRINTSTRING (10, 110), "6 = Hollow Gear Size INCREASE"
_PRINTSTRING (10, 126), "7 = Hollow Gear Size DECREASE"
_PRINTSTRING (10, 142), "8 = Solid Gear Size INCREASE"
_PRINTSTRING (10, 158), "9 = Solid Gear Size DECREASE"
_PRINTSTRING (10, 174), "0 = Set Random Pen Color"
_PRINTSTRING (10, 190), "Q = Pen Hole Move OUT"
_PRINTSTRING (10, 206), "A = Pen Hole Move IN"
_PRINTSTRING (10, 222), "W = Speed Up Drawing"
_PRINTSTRING (10, 238), "S = Slow Down Drawing"


'  ------------------------------------------------------------------

NumberOfTeethHollowGearInside = 130
NumberOfTeethHollowGearOutside = NumberOfTeethHollowGearInside + 28
NumberOfTeethSolidGear = 40
PenHoleDistancePercent = 80

HollowGearPixelSize = ((NumberOfTeethHollowGearOutside * ToothSize) / _PI) * Scale + 1
SolidGearPixelSize = (((NumberOfTeethSolidGear * ToothSize) / _PI)) * Scale + 1

SolidGearPenHoleRadius = (SolidGearPixelSize / 2 - CutDepth - 14) / 100 * PenHoleDistancePercent + 6

HollowGear = _NEWIMAGE(HollowGearPixelSize, HollowGearPixelSize, 32)
SolidGear = _NEWIMAGE(SolidGearPixelSize, SolidGearPixelSize, 32)
DrawingPaper = _NEWIMAGE(_WIDTH(0), _HEIGHT(0), 32)


'  DRAW HOLLOW GEAR ON HOLLOWGEAR IMAGE

DrawHollowGear HollowGear, _WIDTH(HollowGear) / 2, _HEIGHT(HollowGear) / 2, NumberOfTeethHollowGearInside, NumberOfTeethHollowGearOutside, ToothSize, CutDepth, Scale
DrawSolidGear SolidGear, _WIDTH(SolidGear) / 2, _HEIGHT(SolidGear) / 2, NumberOfTeethSolidGear, ToothSize, CutDepth, Scale, SolidGearPenHoleRadius

ToothSpin = (360 / (NumberOfTeethHollowGearInside - NumberOfTeethSolidGear)) / 2

_DEST DrawingPaper
CLS , _RGB32(220, 220, 220)

_DEST 0

SolidGearOffsetRadius = (((NumberOfTeethHollowGearInside * ToothSize) / _PI) / 2) * Scale - _HEIGHT(SolidGear) / 2
SolidGearPenHoleRadius = (SolidGearPixelSize / 2 - CutDepth - 14) / 100 * PenHoleDistancePercent + 6
SolidGearAnglePosition = 0
SolidGearAngleRotation = 0

Circumference1 = (NumberOfTeethHollowGearInside + 1) * ToothSize
Circumference2 = (NumberOfTeethSolidGear + 1) * ToothSize
SolidGearSpin = (Circumference1 / Circumference2)

SolidGearOffsetX = CenterX + SolidGearOffsetRadius * SIN(SolidGearAnglePosition * Degree)
SolidGearOffsetY = CenterY - SolidGearOffsetRadius * COS(SolidGearAnglePosition * Degree)
SolidGearHoleX = SolidGearOffsetX - SolidGearPenHoleRadius * SIN(SolidGearAngleRotation * Degree)
SolidGearHoleY = SolidGearOffsetY - SolidGearPenHoleRadius * COS(SolidGearAngleRotation * Degree)

SolidGearOffsetXOld = SolidGearOffsetX
SolidGearOffsetYOld = SolidGearOffsetY
SolidGearHoleXOld = SolidGearHoleX
SolidGearHoleYOld = SolidGearHoleY



DO


   _LIMIT 30

   _DEST DrawingPaper

   FOR i = 1 TO DrawingSpeed

       k& = _KEYHIT

       SELECT CASE k&
           CASE 27 '  <ESC> - EXIT THE DEMO

               SYSTEM

           CASE 48 '  <0> - CHANGE PEN COLOR

               PenColor = _RGB32(RND * 256, RND * 256, RND * 256)

           CASE 49 '  <1> - TURN ON/OFF PEN

               IF PenOn = TRUE THEN
                   PenOn = FALSE
               ELSE
                   PenOn = TRUE
               END IF

           CASE 50 '  <2> - TURN ON/OFF SOLID GEARS MOVEMENT

               IF SolidGearMoving = TRUE THEN
                   SolidGearMoving = FALSE
               ELSE
                   SolidGearMoving = TRUE
               END IF

           CASE 51 '  <3> - PEN SIZE INCREASE

               PenSize = PenSize + 1

           CASE 52 '  <4> - PEN SIZE DECREASE

               IF PenSize > PenSizeMin THEN PenSize = PenSize - 1

           CASE 53 '  <5> - ERASE DRAWINGS IN DRAWING PAPER

               _DEST DrawingPaper
               CLS , _RGB32(240, 240, 240)

           CASE 54 '  <6> - INCREASE HOLLOW GEAR SIZE

               _FREEIMAGE HollowGear

               NumberOfTeethHollowGearInside = NumberOfTeethHollowGearInside + 1
               NumberOfTeethHollowGearOutside = NumberOfTeethHollowGearInside + 28
               HollowGearPixelSize = ((NumberOfTeethHollowGearOutside * ToothSize) / _PI) * Scale + 1

               HollowGear = _NEWIMAGE(HollowGearPixelSize, HollowGearPixelSize, 32)

               DrawHollowGear HollowGear, _WIDTH(HollowGear) / 2, _HEIGHT(HollowGear) / 2, NumberOfTeethHollowGearInside, NumberOfTeethHollowGearOutside, ToothSize, CutDepth, Scale
               ToothSpin = (360 / (NumberOfTeethHollowGearInside - NumberOfTeethSolidGear)) / 2
               SolidGearOffsetRadius = (((NumberOfTeethHollowGearInside * ToothSize) / _PI) / 2) * Scale - _HEIGHT(SolidGear) / 2

               Circumference1 = (NumberOfTeethHollowGearInside) * ToothSize
               Circumference2 = (NumberOfTeethSolidGear) * ToothSize
               SolidGearSpin = (Circumference1 / Circumference2)

               SolidGearOffsetX = CenterX + SolidGearOffsetRadius * SIN(SolidGearAnglePosition * Degree)
               SolidGearOffsetY = CenterY - SolidGearOffsetRadius * COS(SolidGearAnglePosition * Degree)
               SolidGearHoleX = SolidGearOffsetX - SolidGearPenHoleRadius * SIN(SolidGearAngleRotation * Degree)
               SolidGearHoleY = SolidGearOffsetY - SolidGearPenHoleRadius * COS(SolidGearAngleRotation * Degree)

               SolidGearOffsetXOld = SolidGearOffsetX
               SolidGearOffsetYOld = SolidGearOffsetY
               SolidGearHoleXOld = SolidGearHoleX
               SolidGearHoleYOld = SolidGearHoleY

           CASE 55 '  <7> - DECREASE HOLLOW GEAR SIZE

               _FREEIMAGE HollowGear

               IF NumberOfTeethHollowGearInside > HollowGearMinTeeth THEN NumberOfTeethHollowGearInside = NumberOfTeethHollowGearInside - 1
               NumberOfTeethHollowGearOutside = NumberOfTeethHollowGearInside + 28
               HollowGearPixelSize = ((NumberOfTeethHollowGearOutside * ToothSize) / _PI) * Scale + 1

               HollowGear = _NEWIMAGE(HollowGearPixelSize, HollowGearPixelSize, 32)

               DrawHollowGear HollowGear, _WIDTH(HollowGear) / 2, _HEIGHT(HollowGear) / 2, NumberOfTeethHollowGearInside, NumberOfTeethHollowGearOutside, ToothSize, CutDepth, Scale
               ToothSpin = (360 / (NumberOfTeethHollowGearInside - NumberOfTeethSolidGear)) / 2
               SolidGearOffsetRadius = (((NumberOfTeethHollowGearInside * ToothSize) / _PI) / 2) * Scale - _HEIGHT(SolidGear) / 2

               Circumference1 = (NumberOfTeethHollowGearInside) * ToothSize
               Circumference2 = (NumberOfTeethSolidGear) * ToothSize
               SolidGearSpin = (Circumference1 / Circumference2)

               SolidGearOffsetX = CenterX + SolidGearOffsetRadius * SIN(SolidGearAnglePosition * Degree)
               SolidGearOffsetY = CenterY - SolidGearOffsetRadius * COS(SolidGearAnglePosition * Degree)
               SolidGearHoleX = SolidGearOffsetX - SolidGearPenHoleRadius * SIN(SolidGearAngleRotation * Degree)
               SolidGearHoleY = SolidGearOffsetY - SolidGearPenHoleRadius * COS(SolidGearAngleRotation * Degree)

               SolidGearOffsetXOld = SolidGearOffsetX
               SolidGearOffsetYOld = SolidGearOffsetY
               SolidGearHoleXOld = SolidGearHoleX
               SolidGearHoleYOld = SolidGearHoleY

           CASE 56 '  <8> - INCREASE SOLID GEAR SIZE

               _FREEIMAGE SolidGear

               NumberOfTeethSolidGear = NumberOfTeethSolidGear + 1
               SolidGearPixelSize = (((NumberOfTeethSolidGear * ToothSize) / _PI)) * Scale + 1

               SolidGear = _NEWIMAGE(SolidGearPixelSize, SolidGearPixelSize, 32)
               SolidGearPenHoleRadius = (SolidGearPixelSize / 2 - CutDepth - 14) / 100 * PenHoleDistancePercent + 6
               DrawSolidGear SolidGear, _WIDTH(SolidGear) / 2, _HEIGHT(SolidGear) / 2, NumberOfTeethSolidGear, ToothSize, CutDepth, Scale, SolidGearPenHoleRadius

               ToothSpin = (360 / (NumberOfTeethHollowGearInside - NumberOfTeethSolidGear)) / 2
               SolidGearOffsetRadius = (((NumberOfTeethHollowGearInside * ToothSize) / _PI) / 2) * Scale - _HEIGHT(SolidGear) / 2

               SolidGearOffsetX = CenterX + SolidGearOffsetRadius * SIN(SolidGearAnglePosition * Degree)
               SolidGearOffsetY = CenterY - SolidGearOffsetRadius * COS(SolidGearAnglePosition * Degree)
               SolidGearHoleX = SolidGearOffsetX - SolidGearPenHoleRadius * SIN(SolidGearAngleRotation * Degree)
               SolidGearHoleY = SolidGearOffsetY - SolidGearPenHoleRadius * COS(SolidGearAngleRotation * Degree)

               Circumference1 = (NumberOfTeethHollowGearInside) * ToothSize
               Circumference2 = (NumberOfTeethSolidGear) * ToothSize
               SolidGearSpin = (Circumference1 / Circumference2)

               SolidGearOffsetXOld = SolidGearOffsetX
               SolidGearOffsetYOld = SolidGearOffsetY
               SolidGearHoleXOld = SolidGearHoleX
               SolidGearHoleYOld = SolidGearHoleY

           CASE 57 '  <9> - DECREASE SOLID GEAR SIZE

               _FREEIMAGE SolidGear

               IF NumberOfTeethSolidGear > SolidGearMinTeeth THEN NumberOfTeethSolidGear = NumberOfTeethSolidGear - 1
               SolidGearPixelSize = (((NumberOfTeethSolidGear * ToothSize) / _PI)) * Scale + 1

               SolidGear = _NEWIMAGE(SolidGearPixelSize, SolidGearPixelSize, 32)
               SolidGearPenHoleRadius = (SolidGearPixelSize / 2 - CutDepth - 14) / 100 * PenHoleDistancePercent + 6
               DrawSolidGear SolidGear, _WIDTH(SolidGear) / 2, _HEIGHT(SolidGear) / 2, NumberOfTeethSolidGear, ToothSize, CutDepth, Scale, SolidGearPenHoleRadius

               ToothSpin = (360 / (NumberOfTeethHollowGearInside - NumberOfTeethSolidGear)) / 2
               SolidGearOffsetRadius = (((NumberOfTeethHollowGearInside * ToothSize) / _PI) / 2) * Scale - _HEIGHT(SolidGear) / 2

               SolidGearOffsetX = CenterX + SolidGearOffsetRadius * SIN(SolidGearAnglePosition * Degree)
               SolidGearOffsetY = CenterY - SolidGearOffsetRadius * COS(SolidGearAnglePosition * Degree)
               SolidGearHoleX = SolidGearOffsetX - SolidGearPenHoleRadius * SIN(SolidGearAngleRotation * Degree)
               SolidGearHoleY = SolidGearOffsetY - SolidGearPenHoleRadius * COS(SolidGearAngleRotation * Degree)

               Circumference1 = (NumberOfTeethHollowGearInside) * ToothSize
               Circumference2 = (NumberOfTeethSolidGear) * ToothSize
               SolidGearSpin = (Circumference1 / Circumference2)

               SolidGearOffsetXOld = SolidGearOffsetX
               SolidGearOffsetYOld = SolidGearOffsetY
               SolidGearHoleXOld = SolidGearHoleX
               SolidGearHoleYOld = SolidGearHoleY


           CASE 113, 81 ' <q> or <Q> - MOVE THE PEN HOLE TO THE OUTSIDE OF THE SOLID GEAR

               IF PenHoleDistancePercent < 100 THEN
                   _FREEIMAGE SolidGear

                   SolidGearPixelSize = (((NumberOfTeethSolidGear * ToothSize) / _PI)) * Scale + 1
                   SolidGear = _NEWIMAGE(SolidGearPixelSize, SolidGearPixelSize, 32)
                   PenHoleDistancePercent = PenHoleDistancePercent + 1
                   SolidGearPenHoleRadius = (SolidGearPixelSize / 2 - CutDepth - 14) / 100 * PenHoleDistancePercent + 6

                   DrawSolidGear SolidGear, _WIDTH(SolidGear) / 2, _HEIGHT(SolidGear) / 2, NumberOfTeethSolidGear, ToothSize, CutDepth, Scale, SolidGearPenHoleRadius

                   SolidGearOffsetX = CenterX + SolidGearOffsetRadius * SIN(SolidGearAnglePosition * Degree)
                   SolidGearOffsetY = CenterY - SolidGearOffsetRadius * COS(SolidGearAnglePosition * Degree)
                   SolidGearHoleX = SolidGearOffsetX - SolidGearPenHoleRadius * SIN(SolidGearAngleRotation * Degree)
                   SolidGearHoleY = SolidGearOffsetY - SolidGearPenHoleRadius * COS(SolidGearAngleRotation * Degree)

                   SolidGearOffsetXOld = SolidGearOffsetX
                   SolidGearOffsetYOld = SolidGearOffsetY
                   SolidGearHoleXOld = SolidGearHoleX
                   SolidGearHoleYOld = SolidGearHoleY

               END IF

           CASE 97, 65 '  <a> or <A> - MOVE THE HOLE TO THE INSIDE OF THE SOLID GEAR

               IF PenHoleDistancePercent > 0 THEN
                   _FREEIMAGE SolidGear

                   SolidGearPixelSize = (((NumberOfTeethSolidGear * ToothSize) / _PI)) * Scale + 1
                   SolidGear = _NEWIMAGE(SolidGearPixelSize, SolidGearPixelSize, 32)
                   PenHoleDistancePercent = PenHoleDistancePercent - 1
                   SolidGearPenHoleRadius = (SolidGearPixelSize / 2 - CutDepth - 14) / 100 * PenHoleDistancePercent + 6

                   DrawSolidGear SolidGear, _WIDTH(SolidGear) / 2, _HEIGHT(SolidGear) / 2, NumberOfTeethSolidGear, ToothSize, CutDepth, Scale, SolidGearPenHoleRadius

                   SolidGearOffsetX = CenterX + SolidGearOffsetRadius * SIN(SolidGearAnglePosition * Degree)
                   SolidGearOffsetY = CenterY - SolidGearOffsetRadius * COS(SolidGearAnglePosition * Degree)
                   SolidGearHoleX = SolidGearOffsetX - SolidGearPenHoleRadius * SIN(SolidGearAngleRotation * Degree)
                   SolidGearHoleY = SolidGearOffsetY - SolidGearPenHoleRadius * COS(SolidGearAngleRotation * Degree)

                   SolidGearOffsetXOld = SolidGearOffsetX
                   SolidGearOffsetYOld = SolidGearOffsetY
                   SolidGearHoleXOld = SolidGearHoleX
                   SolidGearHoleYOld = SolidGearHoleY

               END IF

           CASE 119, 87 '  <W> or <w> - SPEED UP DRAWING

               DrawingSpeed = DrawingSpeed + 1

           CASE 115, 83 '  <S> or <s> - SLOW DOWN DRAWING

               IF DrawingSpeed > 1 THEN
                   DrawingSpeed = DrawingSpeed - 1
               END IF

           CASE ELSE

       END SELECT

       IF PenOn = TRUE THEN
           FOR x = -(PenSize / 3) TO PenSize / 3
               FOR y = -(PenSize / 3) TO PenSize / 3
                   LINE (SolidGearHoleXOld + x, SolidGearHoleYOld + y)-(SolidGearHoleX + x, SolidGearHoleY + y), PenColor
               NEXT
           NEXT
       END IF


       IF SolidGearMoving = TRUE THEN
           SolidGearOffsetXOld = SolidGearOffsetX
           SolidGearOffsetYOld = SolidGearOffsetY
           SolidGearHoleXOld = SolidGearHoleX
           SolidGearHoleYOld = SolidGearHoleY

           SolidGearAnglePosition = SolidGearAnglePosition + SolidGearSpeed
           SolidGearAngleRotation = SolidGearAngleRotation + SolidGearSpin - 1 ' - SolidGearSpeed)

           SolidGearOffsetX = CenterX + SolidGearOffsetRadius * SIN(SolidGearAnglePosition * Degree)
           SolidGearOffsetY = CenterY - SolidGearOffsetRadius * COS(SolidGearAnglePosition * Degree)
           SolidGearHoleX = SolidGearOffsetX - SolidGearPenHoleRadius * SIN(SolidGearAngleRotation * Degree)
           SolidGearHoleY = SolidGearOffsetY - SolidGearPenHoleRadius * COS(SolidGearAngleRotation * Degree)
       END IF

   NEXT


   _DEST 0

   _PUTIMAGE (0, 0), DrawingPaper, 0
   _PUTIMAGE (2, 2), HelpMenu, 0

   DisplayImage HollowGear, CenterX, CenterY, 0, 0
   DisplayImage SolidGear, SolidGearOffsetX, SolidGearOffsetY, SolidGearAngleRotation, 0

   _DISPLAY


LOOP

SYSTEM



SUB DrawGearOutline (CenterX AS _UNSIGNED INTEGER, CenterY AS _UNSIGNED INTEGER, NumberOfTeeth AS _UNSIGNED INTEGER, ToothSize AS _FLOAT, CutDepth AS _FLOAT, Scale AS _FLOAT)

   Circumference = NumberOfTeeth * ToothSize
   Radius = ((Circumference / _PI) / 2) * Scale
   ArcDegrees = (NumberOfTeeth / 360) * Degree
   ArcDegreesHalf = ArcDegrees / 2
   NumberOfArcs = 360 / NumberOfTeeth

   FOR Degrees = 0 TO 359 STEP NumberOfArcs

       x = CenterX + Radius * SIN(Degrees * Degree)
       y = CenterY - Radius * COS(Degrees * Degree)

       x1 = CenterX + (Radius - CutDepth) * SIN((Degrees + NumberOfArcs / 2) * Degree)
       y1 = CenterY - (Radius - CutDepth) * COS((Degrees + NumberOfArcs / 2) * Degree)

       x2 = CenterX + Radius * SIN((Degrees + NumberOfArcs) * Degree)
       y2 = CenterY - Radius * COS((Degrees + NumberOfArcs) * Degree)

       LINE (x, y)-(x1, y1)
       LINE -(x2, y2)

   NEXT

END SUB


SUB DrawHollowGear (Image AS LONG, CenterX AS _UNSIGNED INTEGER, CenterY AS _UNSIGNED INTEGER, NumberOfInsideTeeth AS _UNSIGNED INTEGER, NumberOfOutsideTeeth AS _UNSIGNED INTEGER, ToothSize AS _FLOAT, CutDepth AS _FLOAT, Scale AS _FLOAT)

   DIM ImageTemp AS LONG
   DIM CircumferenceInside AS _FLOAT
   DIM CircumferenceOutside AS _FLOAT
   DIM RadiusInside AS _FLOAT
   DIM RadiusOutside AS _FLOAT

   ImageTemp = _NEWIMAGE(_WIDTH(Image), _HEIGHT(Image), 32)
   _DEST ImageTemp

   COLOR _RGB32(255, 255, 255)

   CircumferenceInside = NumberOfInsideTeeth * ToothSize
   RadiusInside = ((CircumferenceInside / _PI) / 2) * Scale

   CircumferenceOutside = NumberOfOutsideTeeth * ToothSize
   RadiusOutside = ((CircumferenceOutside / _PI) / 2) * Scale

   x = CenterX + (RadiusInside + 15) * SIN(RadiusInside * Degree)
   y = CenterY - (RadiusInside + 15) * COS(RadiusInside * Degree)

   CIRCLE (CenterX, CenterY), RadiusInside + 4
   CIRCLE (CenterX, CenterY), RadiusOutside - (ToothSize * Scale) - 2
   PAINT (x, y), _RGB32(255, 255, 255), _RGB32(255, 255, 255)

   _SETALPHA 190, _RGB32(255, 255, 255)
   _PUTIMAGE (0, 0), ImageTemp, Image

   CLS

   DrawGearOutline CenterX, CenterY, NumberOfInsideTeeth, ToothSize, CutDepth, Scale
   DrawGearOutline CenterX, CenterY, NumberOfOutsideTeeth, ToothSize, CutDepth, Scale

   CIRCLE (CenterX, CenterY), RadiusInside + 4, _RGB32(255, 255, 255)
   CIRCLE (CenterX, CenterY), RadiusOutside - (ToothSize * Scale) - 2, _RGB32(255, 255, 255)

   PAINT (CenterX, CenterY - (RadiusInside + 3)), _RGB32(255, 255, 255), _RGB32(255, 255, 255)
   PAINT (CenterX, CenterY - (RadiusOutside - (ToothSize * Scale))), _RGB32(255, 255, 255), _RGB32(255, 255, 255)

   CIRCLE (CenterX, CenterY), RadiusInside + 4, _RGB32(0, 0, 0)
   CIRCLE (CenterX, CenterY), RadiusOutside - (ToothSize * Scale) - 2, _RGB32(0, 0, 0)

   _SETALPHA 0, _RGB32(0, 0, 0)
   _SETALPHA 80, _RGB32(255, 255, 255)
   _PUTIMAGE (0, 0), ImageTemp, Image

   _DEST Image

   COLOR _RGBA32(64, 64, 64, 96)
   DrawGearOutline CenterX, CenterY, NumberOfInsideTeeth, ToothSize, CutDepth, Scale
   DrawGearOutline CenterX, CenterY, NumberOfOutsideTeeth, ToothSize, CutDepth, Scale

   _FREEIMAGE ImageTemp

END SUB




SUB DrawSolidGear (Image AS LONG, CenterX AS _UNSIGNED INTEGER, CenterY AS _UNSIGNED INTEGER, NumberOfTeeth AS _UNSIGNED INTEGER, ToothSize AS _FLOAT, CutDepth AS _FLOAT, Scale AS _FLOAT, SolidGearPenHoleRadius AS _FLOAT)

   DIM ImageTemp AS LONG
   DIM Circumference AS _FLOAT
   DIM Radius AS _FLOAT

   ImageTemp = _NEWIMAGE(_WIDTH(Image), _HEIGHT(Image), 32)
   _DEST ImageTemp

   COLOR _RGB32(200, 200, 200)

   Circumference = NumberOfTeeth * ToothSize
   Radius = ((Circumference / _PI) / 2) * Scale

   DrawGearOutline CenterX, CenterY, NumberOfTeeth, ToothSize, CutDepth, Scale

   x = CenterX
   y = CenterY - SolidGearPenHoleRadius
   CIRCLE (x, y), 5

   PAINT (CenterX, CenterY), _RGB32(200, 200, 200), _RGB32(200, 200, 200)

   _SETALPHA 200, _RGB32(200, 200, 200)
   _PUTIMAGE (0, 0), ImageTemp, Image

   CLS
   _SETALPHA 0, _RGB32(0, 0, 0)

   COLOR _RGB32(32, 32, 32)

   LINE (CenterX - Radius, CenterY)-(CenterX + Radius, CenterY)
   LINE (CenterX, CenterY - SolidGearPenHoleRadius + 5)-(CenterX, CenterY + Radius)
   LINE (CenterX, CenterY - SolidGearPenHoleRadius - 5)-(CenterX, CenterY - Radius)

   _SETALPHA 128, _RGB32(32, 32, 32)
   _PUTIMAGE (0, 0), ImageTemp, Image

   _DEST Image

   COLOR _RGBA32(64, 64, 64, 96)
   DrawGearOutline CenterX, CenterY, NumberOfTeeth, ToothSize, CutDepth, Scale
   CIRCLE (x, y), 5, _RGBA32(64, 64, 64, 200)

   _FREEIMAGE ImageTemp

END SUB



SUB DisplayImage (Image AS LONG, x AS INTEGER, y AS INTEGER, angle AS SINGLE, mode AS _BYTE)
   'Image is the image handle which we use to reference our image.
   'x,y is the X/Y coordinates where we want the image to be at on the screen.
   'angle is the angle which we wish to rotate the image.
   'mode determines HOW we place the image at point X,Y.
   'Mode 0 we center the image at point X,Y
   'Mode 1 we place the Top Left corner of our image at point X,Y
   'Mode 2 is Bottom Left
   'Mode 3 is Top Right
   'Mode 4 is Bottom Right


   DIM px(3) AS INTEGER, py(3) AS INTEGER, w AS INTEGER, h AS INTEGER
   DIM sinr AS SINGLE, cosr AS SINGLE, i AS _BYTE
   w = _WIDTH(Image): h = _HEIGHT(Image)
   SELECT CASE mode
       CASE 0 'center
           px(0) = -w \ 2: py(0) = -h \ 2
           px(3) = w \ 2: py(3) = -h \ 2
           px(1) = -w \ 2: py(1) = h \ 2
           px(2) = w \ 2: py(2) = h \ 2
       CASE 1 'top left
           px(0) = 0: py(0) = 0
           px(3) = w: py(3) = 0
           px(1) = 0: py(1) = h
           px(2) = w: py(2) = h
       CASE 2 'bottom left
           px(0) = 0: py(0) = -h
           px(3) = w: py(3) = -h
           px(1) = 0: py(1) = 0
           px(2) = w: py(2) = 0
       CASE 3 'top right
           px(0) = -w: py(0) = 0
           px(3) = 0: py(3) = 0
           px(1) = -w: py(1) = h
           px(2) = 0: py(2) = h
       CASE 4 'bottom right
           px(0) = -w: py(0) = -h
           px(3) = 0: py(3) = -h
           px(1) = -w: py(1) = 0: px(2) = 0: py(2) = 0
   END SELECT

   sinr = SIN(angle / 57.2957795131)
   cosr = COS(angle / 57.2957795131)

   FOR i = 0 TO 3
       x2 = (px(i) * cosr + sinr * py(i)) + x
       y2 = (py(i) * cosr - px(i) * sinr) + y
       px(i) = x2
       py(i) = y2
   NEXT

   _MAPTRIANGLE _SEAMLESS(0, 0)-(0, h - 1)-(w - 1, h - 1), Image TO(px(0), py(0))-(px(1), py(1))-(px(2), py(2)), , _SMOOTH
   _MAPTRIANGLE _SEAMLESS(0, 0)-(w - 1, 0)-(w - 1, h - 1), Image TO(px(0), py(0))-(px(3), py(3))-(px(2), py(2)), , _SMOOTH

END SUB

This code in this demo can be optimized a bit more as there are redundant pieces, but I am not up t doing so at this point.

Please help support The Joyful Programmer and The QB64 Edition by visiting our online store provided by Amazon.com. We hand-picked books related to computer programming from Amazon.com and added them to our store. When you make a purchase from our store, we do receive a small commission from the sale. Visit our store at: http://www.thejoyfulprogrammer.com/qb64/...azon-store
Find all posts by this user
Like Post
The following 1 user Likes Waltersmind's post:
bplus
07-05-2017, 10:43 AM
Post: #2
 (Print Post)
RE: QB64 Spirograph's by TJP
Outstanding! And this is only first version? Wow!

Variables labeled very clearly, inviting people to follow the code and modify. Wink

B += _
Find all posts by this user
Like Post
07-05-2017, 11:38 AM
Post: #3
 (Print Post)
RE: QB64 Spirograph's by TJP
Brilliant!! What more can I say?

J

May your journey be free of incident.

Live long and prosper.
Find all posts by this user
Like Post
07-05-2017, 12:48 PM
Post: #4
 (Print Post)
RE: QB64 Spirograph's by TJP
Quote:
Brilliant!! What more can I say?

J

Say?

Say how you might modify it with coffee colors, say how you will now be serving coffee on Spirograph doilies, and don't forget the milk for those of us who like their coffee contaminated.  Wink

B += _
Find all posts by this user
Like Post
07-05-2017, 01:34 PM
Post: #5
 (Print Post)
RE: QB64 Spirograph's by TJP
bplus / johnno56,

Thank you both for the compliments.

Bplus, the only reason this crippled demo is the first version is due to my hast in wanting to share it with the community. If I wasn't so anxious to post it, it would have had more features like saving the spiral image, the solid gear drawing on the outside rim of the hollow gear (as I like to call it for now), following other paths, hide/show the help menu as well as the gears, displaying important information like current pen color, pen hole distance and drawing speed, larger & moveable drawing area, better color selections, and possibly more.

While I wanted to get onboard the spirograph craze for a moment, I did have an alterier motive. I wanted to show people what could be done with a little bit of thought, creativity, and research. You do not have to have great knowledge to reproduce this simple little demo, nor do you need great math skills. While this demo may not express my true level of mathematical skills, it does show my ingenuity in replicating an idea. It may come as a shock to many people, but I have basic and limited knowledge of simple Algerbra, Geometry, and a touch of understanding of Trigonometry. I understand the concept of what can be done with physics, but anything I do with it is built on basic mathematics (P.E.M.D.A.S - Parenthesis, Exponents, Multiplication, Division, Addition, and Subtraction). I may not create perfect physic equations like they would teach you in school, I try to find a way in basic mathematics to do the same thing, if possible.

On a side note, I am a typesetter (a basic graphic designer in today's terms) at the company I work at. While I do not have the training, or the understanding of true graphic design, I can do some cool things from time to time. I am really good a recreating most things as long as it isn't too complex. What I have found amusing many times over the years, was that local printshop owners would call me, asking if I could recreate their client's artwork because their graphic artists couldn't.

Now, what does that have to do with this demo? Everything! While I am not a graphic artists or a mathematical genious, I have rule I live by religiously, and that is to break everything down to their simplest components. In the artwork I have recreated over the years, I break everything down to individual shapes and colors.

I have always wanted to create a demo that drew gears on screen, but I always found something else to do instead. However, this spirograph demo was the perfect excuse to do so.

How did I create the gears? Simple. I broke the gear down into its teeth. First, I ask myself, "How do they make the teeth of a gear?" Well, some years ago I saw an episode of "How It's Made" which showed how some companies do it. Here is the video on YouTube:




So basically, they use a special cutting blade to slowly cut grooves into the material that will be the gear.

While thinking about a finished gear, I realized that you can define two different radius's for the gear. The overall radius of the gear with teeth, and the radius to the bottom of the teeth, which can be determined by the cut size made by the cutting blade.

This helped in one aspect, but I needed to figure out what size to make the circumference of the "blank" so that the teeth are the same size and distant apart on various sized gears. After starring at the teeth for a moment, I realized all I needed to do was measure the distance of two teeth on the gear. While I didn't have a gear in hand to measure, I decided on a distance of 3/16". Then I had a eureka moment. I realized that I could simple define the size of the gear by the number of cuts (to make the teeth) I wanted.

From this idea, I was able to create a basic equation, "Circumference = CutSize * NumberOfCuts". However, since I was wanting to draw a gear on the computer screen, I needed to know the radius of the gear. This was very easy to do, especially after Googling for the solution. We know that a circumference of a circle is calculated with "Circumference = PI * (Radius * Radius)" To calculate the Radius from the circumference you would use "Radius = (Circumference / PI) / 2".

However, I ran into a small issue. Literally. When I drew the gears on screen with those formulas, all I got was a small bloby circle. I realized I was using inches as pixels and I needed to convert those numbers correctly so the gear could be displayed on screen. So, what did I do? Well, I continued using inches as pixels. However, since 1.5" (arbitrary number pulled out of the proverbial hat) converted to 1.5-Pixels is way too small, I needed to scale that number up, which I did by a factor of 100. It was a good number to start with, and it worked so I had no intentions of changing it.

Now that I can easily pick a random number of cuts for the gear, I can now convert the size of the cuts to degrees by using "Degrees = 360 / NumberOfCuts", and presto! Perfect gears.

Now how was I going to calculate the solid gear speed as it goes around inside edge of the hollow gear so that the teeth? Well, looking at both gears on screen for a few moments, I realized fairly quickly that if the solid gear was half the diameter of the inner part of the hollow gear, it would need to rotate 360 degrees twice. To prove that, if you laid the solid gears circumference flat against the inner circumference of the hollow gear, it would be half the size. So in turn, I would need to rotate the solid gear in two degree increments. I also quickly realized I should rotate the solid gear around the inner circumference by the same amount of degrees. Presto! That logical thinking prooved to work when I was able to animate the solid gear around the inner circumference of the hollow gear.

Now the hard stuff was out of the way, let's get to the graphics.

I knew I wanted the gears and help menu to float on top of the spirograph drawing without affecting the drawing itself. This was the easy part. Each graphical element (menu, hollow gear, solid gear, and drawing area) was stored in an individual image (in memory) and then drawn to the screen, one overlaying another. The solid gear was rotated as it was being drawn to the screen. Also, all drawings were done on the drawing area image only. The only thing that is drawn during the course of the animation, besides the images to screen, were lines on the drawing area image.

Oh, a little side note, when the pen hole is closes to the outer rim of the solid gear, it is at 100%. When it is at its closest to the center of the gear, it is at 0%. The percentages are converted to 1 and 0. That way, the hole would stay in the same relative position if the gear size changes.

I hope this information helps.

Please help support The Joyful Programmer and The QB64 Edition by visiting our online store provided by Amazon.com. We hand-picked books related to computer programming from Amazon.com and added them to our store. When you make a purchase from our store, we do receive a small commission from the sale. Visit our store at: http://www.thejoyfulprogrammer.com/qb64/...azon-store
Find all posts by this user
Like Post
The following 1 user Likes Waltersmind's post:
bplus
07-05-2017, 03:22 PM
Post: #6
 (Print Post)
RE: QB64 Spirograph's by TJP
Hi Walter,

That was really nice follow up post! (There the spellchecker worked followup no good)
You get a story along with the code and screen shot and movie! I have to say as far as writing goes this was good because based on true experience (as opposed to exercises in fiction).

I too had an interest in making gears, my approach much different than yours. My mistake may have been looking at gear blue prints flummoxed by the shape of the teeth!

I was also a machine operator CNC lathes, having been one I know I am not allowed to say I was a machinist and be correct. So, watching the process of gears being made was very interesting to me.

For laughs, here is as far as I got before I let others distractions distract me from Gear Maker.


Attached File(s) Image(s)
   

B += _
Find all posts by this user
Like Post
07-05-2017, 11:48 PM
Post: #7
 (Print Post)
RE: QB64 Spirograph's by TJP
Mark,

One of main main goals on this forum is to be as educational as possible. To me, showing off my skills is extremely boring because it is only a instant gratification that no one but myself will enjoy. However, if we can teach the community how to do things, then the community will hugely benefit from it. Not only will they get better knowledge and new skills ("if they so choose to accept the mission"), but it could be a life changer for them in so way, shape, or form.

As I have told many people over the years, as well as extraterrestrials, there are a million-and-one ways to do the same thing in computer programming.

The way you were looking at the problem of creating gears on the computer screen was ingenious.

Please help support The Joyful Programmer and The QB64 Edition by visiting our online store provided by Amazon.com. We hand-picked books related to computer programming from Amazon.com and added them to our store. When you make a purchase from our store, we do receive a small commission from the sale. Visit our store at: http://www.thejoyfulprogrammer.com/qb64/...azon-store
Find all posts by this user
Like Post



Forum Jump:


User(s) browsing this thread: 1 Guest(s)




QB64 Member Project - ARB Checkers
QB64 Member Project - Dreamy Clock
QB64 Member Project - Input
QB64 Member Project - RGB Color Wheel
QB64 Member Project - Qubic
QB64 Member Project - Sabotage
QB64 Member Project - Color Rotating Text
QB64 Member Project - Bowditch curve
QB64 Member Project - Pivet version one
QB64 Member Project - Rotating Background
QB64 Member Project - MAPTRIANGLE
QB64 Member Project - Line Thickness
QB64 Member Project - Quarto
QB64 Member Project - Score 4
QB64 Member Project - Martin Fractals version one
QB64 Member Project - Rubix's Magic
QB64 Member Project - Algeria Weather
QB64 Member Project - Blokus
QB64 Member Project - Kings Vallery version two
QB64 Member Project - OpenGL Triangles
QB64 Member Project - Swirl
QB64 Member Project - Martin Fractals version four
QB64 Member Project - Othello
QB64 Member Project - Exit
QB64 Member Project - Pivot version two
QB64 Member Project - Red Scrolling LED Sign
QB64 Member Project - Isolation
QB64 Member Project - Connect Four
QB64 Member Project - Spiro Roses
QB64 Member Project - Color Triangles
QB64 Member Project - Kings Valley verion one
QB64 Member Project - Amazon
QB64 Member Project - Foursight
QB64 Member Project - Point Blank
QB64 Member Project - Domain
QB64 Member Project - Spinning Color Wheel
QB64 Member Project - Kings Court
QB64 Member Project - Splatter
QB64 Member Project - Martin Fractals version two
QB64 Member Project - STxAxTIC 3D World
QB64 Member Project - Martin Fractals version three
QB64 Member Project - 9 Board
QB64 Member Project - Kobolts Monopoly
QB64 Member Project - Touche
QB64 Member Project - Basic Dithering
QB64 Member Project - Full Color LED Sign
QB64 Member Project - Inside Moves
QB64 Member Project - Overboard
QB64 Member Project - Dakapo