Yesterday I had seen a video to draw the relative positions of the planets Venus and Earth.
https://www.youtube.com/watch?v=_CAtiymmOaU
I wanted to do it in HMG with various parameters. The result is amazing! Hope you like it.
A request to Claudio:
Can we draw a line or other shapes transparently like the video?
Code: Select all
#include <hmg.ch>
Function Main
define window cm at 0, 0 width 800 height 600 main title 'Circle Magic'
define button draw
row 10
col 10
caption 'Draw'
width 50
action draw()
end button
define label innerrlabel
row 15
col 70
width 90
value 'Inner Planet R'
end label
define spinner innerr
row 10
col 160
width 60
rangemin 5
rangemax 150
increment 5
value 80
end spinner
define label outerrlabel
row 15
col 230
width 90
value 'Outer Planet R'
end label
define spinner outerr
row 10
col 320
width 60
rangemin 5
rangemax 200
increment 5
value 110
end spinner
define label innerspeed
row 45
col 70
width 90
value 'Inner Speed'
end label
define spinner speed
row 40
col 160
width 60
rangemin 1
rangemax 50
value 20
increment 1
end spinner
define label outerspeed
row 45
col 230
width 90
value 'Outer Speed'
end label
define spinner ospeed
row 40
col 320
width 60
rangemin 1
rangemax 50
value 3
increment 1
end spinner
define label revolutionslabel
row 45
col 390
width 90
value 'Revolutions'
end label
define spinner revolutions
row 40
col 480
width 60
rangemin 1
rangemax 50
value 1
increment 1
end spinner
define checkbox stereo
row 40
col 550
width 70
caption 'Stereo'
backcolor { 255, 255, 0 }
value .f.
end checkbox
define spinner base
row 40
col 630
width 60
rangemin 2
rangemax 50
value 20
increment 2
end spinner
define label backcolorlabel
row 75
col 70
width 90
value 'Back Color'
end label
define label backcolor
row 70
col 160
width 60
height 20
backcolor { 255, 255, 255 }
onclick getbackcolor()
end label
define label pencolorlabel
row 75
col 230
width 90
value 'Pen Color'
end label
define label pencolor
row 70
col 320
width 60
height 20
backcolor { 255, 0, 0 }
onclick getpencolor()
end label
define checkbox randomcolor
row 70
col 390
width 90
caption 'Use Random'
end checkbox
define checkbox singlecolor
row 70
col 490
width 90
caption 'Single Color'
end checkbox
define label animationspeed
row 15
col 580
width 100
value 'Animation Speed'
end label
define spinner anispeed
row 10
col 680
width 80
rangemin 1000
rangemax 100000
value 50000
increment 5000
end spinner
end window
cm.center
cm.activate
Return
function drawstereo
LOCAL hDC, BTstruct
local nSmallRadius := cm.innerr.value
local nBigRadius := cm.outerr.value
local nBigRevolutions := cm.revolutions.value
local nInnerSpeed := cm.speed.value
local nOuterSpeed := cm.ospeed.value
local nCenterCol := 400
local nCenterRow := 300
local nSmallRow := 0
local nSmallCol := 0
local nBigRow := 0
local nBigCol := 0
local nDotRadius := 1
local nSmallDots := 360
local nBigDots := round( nSmallDots * nBigRadius / nSmallRadius, 0 )
local aLSmall := {}
local aLBig := {}
local aRSmall := {}
local aRBig := {}
local nRadians := 0.0174532925
local nSmallCount := 0
local nBigCount := 0
local nMax := 150
local nAniSpeed := cm.anispeed.value
local nStereoBase := cm.base.value
local nLSmallCenterCol := nCenterCol - 200 - ( nStereoBase / 2 )
local nRSmallCenterCol := nCenterCol + 200 + ( nStereoBase / 2 )
local nLBigCenterCol := nCenterCol - 200 + ( nStereoBase / 2 )
local nRBigCenterCol := nCenterCol + 200 - ( nStereoBase / 2 )
if nSmallRadius < 10
nSmallRadius := 10
cm.innerr.value := nSmallRadius
endif
if nBigRadius > nMax
nBigRadius := nMax
cm.outerr.value := nBigRadius
endif
if nSmallRadius > nBigRadius + 10
nSmallRadius := nBigRadius - 10
cm.innerr.value := nSmallRadius
endif
if nBigRadius <= nSmallRadius + 10
nBigRadius := nSmallRadius + 10
cm.outerr.value := nBigRadius
endif
hDC := BT_CreateDC ( "cm", BT_HDC_ALLCLIENTAREA, @BTstruct )
BT_DrawFillRectangle (hDC, 150, 20, 770, 300, cm.backcolor.backcolor, cm.backcolor.backcolor, 1)
for i := 1 to nSmallDots
nSmallRow := nCenterRow + nSmallRadius * Cos( i / ( nSmallDots / 360 ) * nRadians )
nSmallCol := nCenterCol + nSmallRadius * Sin( i / ( nSmallDots / 360 ) * nRadians )
nLSmallCol := nLSmallCenterCol + nSmallRadius * Sin( i / ( nSmallDots / 360 ) * nRadians )
nRSmallCol := nRSmallCenterCol + nSmallRadius * Sin( i / ( nSmallDots / 360 ) * nRadians )
aadd( aLSmall, { nSmallRow, nLSmallCol } )
aadd( aRSmall, { nSmallRow, nRSmallCol } )
&& if msgyesno( str( nSmallRow ) + ' ' + str( nLSmallCol ) + ' ' + str( nSmallRow ) + ' ' + str( nRSmallCol ) )
&& BT_DeleteDC (BTstruct)
&& return nil
&& endif
// BT_DrawEllipse ( hDC, nSmallRow, nSmallCol, nDotRadius, nDotRadius, { 0, 0, 0 } )
// BT_DrawEllipse ( hDC, nSmallRow, nLSmallCol, nDotRadius, nDotRadius, { 0, 0, 0 } )
BT_DrawEllipse ( hDC, nSmallRow, nLSmallCol, nDotRadius, nDotRadius, { 0, 0, 0 } )
BT_DrawEllipse ( hDC, nSmallRow, nRSmallCol, nDotRadius, nDotRadius, { 0, 0, 0 } )
next i
for i := 1 to nBigDots
nBigCol := nCenterCol + nBigRadius * Sin( i / ( nBigDots / 360 ) * nRadians )
nBigRow := nCenterRow + nBigRadius * Cos( i / ( nBigDots / 360 ) * nRadians )
nLBigCol := nLBigCenterCol + nBigRadius * Sin( i / ( nBigDots / 360 ) * nRadians )
nRBigCol := nRBigCenterCol + nBigRadius * Sin( i / ( nBigDots / 360 ) * nRadians )
aadd( aLBig, { nBigRow, nLBigCol } )
aadd( aRBig, { nBigRow, nRBigCol } )
BT_DrawEllipse ( hDC, nBigRow, nLBigCol, nDotRadius, nDotRadius, { 0, 0, 0 } )
BT_DrawEllipse ( hDC, nBigRow, nRBigCol, nDotRadius, nDotRadius, { 0, 0, 0 } )
next i
&& BT_DeleteDC (BTstruct)
&& RETURN
nSmallCount := 1
nBigCount := 1
if cm.singlecolor.value
if cm.randomcolor.value
nR := random( 255 )
nG := random( 255 )
nB := random( 255 )
else
aRGB := cm.pencolor.backcolor
nR := aRGB[ 1 ]
nG := aRGB[ 2 ]
nB := aRGB[ 3 ]
endif
endif
nCount := int( nBigDots * nBigRevolutions / nOuterSpeed )
for i := 1 to nCount
nBigCount := nBigCount + nOuterSpeed
nSmallCount := nSmallCount + nInnerSpeed
if nSmallCount > nSmallDots
nSmallCount := nSmallCount - nSmallDots
endif
if nBigCount > nBigDots
nBigCount := nBigCount - nBigDots
endif
if cm.randomcolor.value .and. .not. cm.singlecolor.value
nR := random( 255 )
nG := random( 255 )
nB := random( 255 )
endif
nSmallRow := aLSmall[ nSmallCount, 1 ]
nLSmallCol := aLSmall[ nSmallCount, 2 ]
nRSmallCol := aRSmall[ nSmallCount, 2 ]
nBigRow := aLBig[ nBigCount, 1 ]
nLBigCol := aLBig[ nBigCount, 2 ]
nRBigCol := aRBig[ nBigCount, 2 ]
BT_DrawLine ( hDC, nSmallRow, nLSmallCol, nBigRow, nLBigCol, { nR, nG, nB } )
BT_DrawLine ( hDC, nSmallRow, nRSmallCol, nBigRow, nRBigCol, { nR, nG, nB } )
for j := 1 to nAniSpeed
next j
Do Events
next i
BT_DeleteDC (BTstruct)
RETURN
function getbackcolor
local aRGB := cm.backcolor.backcolor
local aNewRGB := aclone( aRGB )
aNewRGB := getcolor( aRGB )
if aNewRGB[ 1 ] <> Nil
cm.backcolor.backcolor := aNewRGB
endif
return nil
function getpencolor
local aRGB := cm.pencolor.backcolor
local aNewRGB := aclone( aRGB )
aNewRGB := getcolor( aRGB )
if aNewRGB[ 1 ] <> Nil
cm.pencolor.backcolor := aNewRGB
endif
return nil
function draw
LOCAL hDC, BTstruct
local nSmallRadius := cm.innerr.value
local nBigRadius := cm.outerr.value
local nBigRevolutions := cm.revolutions.value
local nInnerSpeed := cm.speed.value
local nOuterSpeed := cm.ospeed.value
local nCenterCol := 400
local nCenterRow := 300
local nSmallRow := 0
local nSmallCol := 0
local nBigRow := 0
local nBigCol := 0
local nDotRadius := 1
local nSmallDots := 360
local nBigDots := round( nSmallDots * nBigRadius / nSmallRadius, 0 )
local aSmall := {}
local aBig := {}
local nRadians := 0.0174532925
local nSmallCount := 0
local nBigCount := 0
local nMax := 200
local nAniSpeed := cm.anispeed.value
if cm.stereo.value
drawstereo()
return nil
endif
if nSmallRadius < 10
nSmallRadius := 10
cm.innerr.value := nSmallRadius
endif
if nBigRadius > nMax
nBigRadius := nMax
cm.outerr.value := nBigRadius
endif
if nSmallRadius > nBigRadius + 10
nSmallRadius := nBigRadius - 10
cm.innerr.value := nSmallRadius
endif
if nBigRadius <= nSmallRadius + 10
nBigRadius := nSmallRadius + 10
cm.outerr.value := nBigRadius
endif
hDC := BT_CreateDC ( "cm", BT_HDC_ALLCLIENTAREA, @BTstruct )
BT_DrawFillRectangle (hDC, 150, 20, 770, 300, cm.backcolor.backcolor, cm.backcolor.backcolor, 1)
for i := 1 to nSmallDots
nSmallRow := nCenterRow + nSmallRadius * Cos( i / ( nSmallDots / 360 ) * nRadians )
nSmallCol := nCenterCol + nSmallRadius * Sin( i / ( nSmallDots / 360 ) * nRadians )
aadd( aSmall, { nSmallRow, nSmallCol } )
BT_DrawEllipse ( hDC, nSmallRow, nSmallCol, nDotRadius, nDotRadius, { 0, 0, 0 } )
next i
for i := 1 to nBigDots
nBigCol := nCenterCol + nBigRadius * Sin( i / ( nBigDots / 360 ) * nRadians )
nBigRow := nCenterRow + nBigRadius * Cos( i / ( nBigDots / 360 ) * nRadians )
aadd( aBig, { nBigRow, nBigCol } )
BT_DrawEllipse ( hDC, nBigRow, nBigCol, nDotRadius, nDotRadius, { 0, 0, 0 } )
next i
nSmallCount := 1
nBigCount := 1
nCount := int( nBigDots * nBigRevolutions / nOuterSpeed )
if cm.singlecolor.value
if cm.randomcolor.value
nR := random( 255 )
nG := random( 255 )
nB := random( 255 )
else
aRGB := cm.pencolor.backcolor
nR := aRGB[ 1 ]
nG := aRGB[ 2 ]
nB := aRGB[ 3 ]
endif
endif
for i := 1 to nCount
nBigCount := nBigCount + nOuterSpeed
nSmallCount := nSmallCount + nInnerSpeed
if nSmallCount > nSmallDots
nSmallCount := nSmallCount - nSmallDots
endif
if nBigCount > nBigDots
nBigCount := nBigCount - nBigDots
endif
if .not. cm.singlecolor.value
nR := random( 255 )
nG := random( 255 )
nB := random( 255 )
endif
nSmallRow := aSmall[ nSmallCount, 1 ]
nSmallCol := aSmall[ nSmallCount, 2 ]
nBigRow := aBig[ nBigCount, 1 ]
nBigCol := aBig[ nBigCount, 2 ]
BT_DrawLine ( hDC, nSmallRow, nSmallCol, nBigRow, nBigCol, { nR, nG, nB } )
for j := 1 to nAniSpeed
next j
Do Events
next i
BT_DeleteDC (BTstruct)
RETURN