|
Post by plus on Feb 26, 2024 18:10:19 GMT
every point is a distance and an angle from another point, here we measure from center of black hole cx, cy.
dx = cx - sx(i): dy = cy - sy(i) d = (dx * dx + dy * dy) ^ .5
dx = distance (and direction) an x is from the center x coordinate dy = distance (and direction) an y is from the center y coordinate
d = magnitude of the distance (no direction) the point x, y is from the point cx, cy the center of screen and origin of Black Hole.
b = Atan2(dy, dx) b = the angle of point x, y to the center cx,cy of the black hole.
the angle a is constantly increasing with every loop adding a to b here newX = cx + d * cos(a + b) newY = cy + d * sin(a + b) swings the x, y point around the center of the Black Hole by angle a added to the angle it was b.
Hope this helps with understanding.
Oh also, Atan2 is read as "the Angle whose tangent is dy/dx" so for the function Atan2 list dy first and dx 2nd. ie if the tangent = some ratio then the Angle to have that was Atan2(dy, dx)
sin cos tan... are all ratios unique to particular angles of right triangles upon which trig is based.
b = b + ...
|
|
|
Post by honky on Feb 27, 2024 9:13:28 GMT
Thank you "plus", I record your explanations and I study your code with it.
Hey, "plus" is a French word, Google Trad tells me "More",
Why a French word on an English-speaking forum ?
|
|
|
Post by plus on Feb 27, 2024 14:45:18 GMT
plus means more or additionally in English too, my original avatar name was B+ like a grade you get from school = paper, essay or test was good but not outstanding
b = b + ...
|
|
|
Post by honky on Feb 27, 2024 16:45:06 GMT
I put A without hesitation
|
|
|
Post by Rod on Feb 28, 2024 13:53:29 GMT
Well this is Rod's contribution. You need to let it run for a while to form the Accretion disk. The star is a data object that has angle and radius as well as x and y so we lose a lot of the maths in forming the spiral. Reduce the number of stars if it is overwhelming your PC. 'PRESS Q TO QUIT 'set up a full screen display 'the same size as the users screen nomainwin WindowWidth=DisplayWidth WindowHeight=DisplayHeight graphicbox #w.gb,0,0,WindowWidth,WindowHeight open "Starfield" for window_popup as #w #w "trapclose [quit]" #w.gb "down"
'set our centre cx=int(WindowWidth/2) cy=int(WindowHeight/2)
'create background for the universe #w.gb "fill 96 96 96 ; size 2" for r=1 to int(WindowWidth/2) #w.gb "place ";cx;" ";cy;" ; circle ";r #w.gb "color ";0+r*.1;" ";0+r*.1;" ";0+r*.1 next
'set up for xor drawing #w.gb "color red" #w.gb "rule xor"
'dim our star object and index values dim star(1000,6) angle=1 radius=2 size=3 xpos=4 ypos=5
'create first set of stars for s = 1 to 1000 star(s,angle) = int(rnd(0)*360) star(s,radius) = int(rnd(0)*DisplayWidth)+500 star(s,size) = int(rnd(0)*3)+1 star(s,xpos) = cx-(star(s,radius)*sin(star(s,angle)/57.29577951)) star(s,ypos) = cy-(star(s,radius)*cos(star(s,angle)/57.29577951)) #w.gb "size ";star(s,size);" ; set ";star(s,xpos);" ";star(s,ypos) next
'set up an event to look for key presses #w.gb "when characterInput [stop]" #w.gb "setfocus"
[move] for s= 1 to 1000 #w.gb "size ";star(s,size);" ; set ";star(s,xpos);" ";star(s,ypos) star(s,radius)=int(star(s,radius)*.9) star(s,angle)=star(s,angle)+3 mod 360 star(s,xpos) = cx-(star(s,radius)*sin(star(s,angle)/57.29577951)) star(s,ypos) = cy-(star(s,radius)*cos(star(s,angle)/57.29577951)) #w.gb "size ";star(s,size);" ; set ";star(s,xpos);" ";star(s,ypos)
if star(s,radius)<25 then #w.gb "size ";star(s,size);" ; set ";star(s,xpos);" ";star(s,ypos) star(s,angle) = int(rnd(0)*360) star(s,radius) = int(rnd(0)*DisplayWidth)+25 star(s,size) = int(rnd(0)*3)+1 star(s,xpos) = cx-(star(s,radius)*sin(star(s,angle)/57.29577951)) star(s,ypos) = cy-(star(s,radius)*cos(star(s,angle)/57.29577951)) #w.gb "size ";star(s,size);" ; set ";star(s,xpos);" ";star(s,ypos) end if scan next goto [move]
[stop] timer 0 w$=right$(Inkey$,1) if w$ = "q" then [quit] wait
[quit] timer 0 close #w end
Attachments:
|
|
|
Post by tsh73 on Feb 28, 2024 18:55:36 GMT
Ahhh, soo many good programs! ;)
Re: Honky's unrealistic colors Well, they might be not that realistic
but it really . really . really feels like old (good) Spectrum days...
Re: Separate glittering ring of stars of B+ Clever! Also, colors are nice.
Re: Rod's 1000-stars galaxy Looks really nice and FAST How you did that? There your CLEAR code? Ah, that's one XOR! Commenting out XOR reveals hidden warp tunnel, have a look! ;) I found kind of problem, though Pressing any key pauses (stops) simulation
Here's last part of program mod, that quits only on "q", and pretty much ignores everything else
end if next scan 'scan after next, so no jumps out of loop goto [move]
[stop] w$=right$(Inkey$,1) if w$ = "q" then timer 0: goto [quit] 'only 'q' quits goto [move] 'else go where SCAN was, to the next iteration
[quit] timer 0 close #w end
|
|
|
Post by tsh73 on Feb 28, 2024 19:08:59 GMT
I got the idea a few days ago - what will happen if star will travel not to hole center, but to tangential point on an accretion circle?
(But how to get the math right?) So to do it I pasted whole vector library (and spent extra evening debugging it. Happens that as now it NEEDS global "pi" variable, atan2 and vectRotate$ do really wierd thing without it.)
But I like what I got stars go tangential - they get sprinning naturally, without any extra +a And looks like they go in spirals closing to R circle (probably never hitting it) but then I set condition to
If d < R+0.001 Then it (mostly) makes several spins around and then passes - to be created outside with
call newStar i
So now stars are attracted to the circle, rotate counterclockwize (you can change to clockwize with vec2$=vectRotate$(vec1$,0-asn(R/d)) ) eventually pass event horison ( ;) ) If d < R+0.001 Then and get reborn outside!
global H$, XMAX, YMAX H$ = "gr" Xmax = 600 '<======================================== actual drawing space needed Ymax = 600 '<======================================== actual drawing space needed global pi 'needs to be here for vector library to work pi = acs(-1)
nomainwin
WindowWidth = Xmax + 8 WindowHeight = Ymax + 32 UpperLeftX = (DisplayWidth - Xmax) / 2 'or delete if XMAX is 1200 or above UpperLeftY = (DisplayHeight - Ymax) / 2 'or delete if YMAX is 700 or above
open "Black Hole Attractor" for graphics_nsb_nf as #gr #gr "trapclose quit" #gr "size 1" #gr "down" #gr "fill 60 0 30"
nstars = 100 'nstars = 60 'nstars = 200 Dim sx(nstars), sy(nstars), sr(nstars) cx = 300: cy = 300 'setup start stars For i = 1 To nstars sx(i) = Rnd(0) * 600 sy(i) = Rnd(0) * 600 sr(i) = Rnd(0) * 3 + 1 Next R=50 R=30 R=40 Do #gr "discard" #gr "fill 60 0 30" 'show stars #gr "color 200 200 200" #gr "backcolor 255 255 255" For i = 1 To nstars vec1$=vect$(cx-sx(i),cy-sy(i)) d = vectLen(vec1$) 'black hole radius 'If d < R+1 Then If d < R+0.001 Then 'so it is slow spiral, and eventually pass call newStar i else 'draw #gr "place ";sx(i);" ";sy(i);"; circlefilled ";sr(i) 'now update stars falling into black hole ' get point on tangential line instead 'vec1$=vect$(cx-sx(i),cy-sy(i)) 'line to center 'alpha=asn(R/vectLen(vec1$)) 'angle of tangential line 'alpha=asn(R/d) vec2$=vectRotate$(vec1$,asn(R/d)) 'dx = cx - sx(i): dy = cy - sy(i) 'dx = val(word$(vec2$,1)) 'so goal point is not center but point on tangential line dx = val(vec2$) 'shorcut: val returns what it could read dy = val(word$(vec2$,2)) ' move it dx = R * dx / (d * d) dy = R * dy / (d * d) sx(i) = sx(i) + dx sy(i) = sy(i) + dy end if Next 'wait '#gr "color 128 0 0" '#gr "backcolor 0 0 0" '#gr "place ";cx;" ";cy;"; circlefilled ";R call pause 30 Loop until something
Sub newStar i r = Int(Rnd(0) * 4) ' 0 to 3 Select Case r Case 0 sx(i) = Rnd(0) * 600 sy(i) = 0 Case 1 sx(i) = Rnd(0) * 600 sy(i) = 599 Case 2 sy(i) = Rnd(0) * 600 sx(i) = 0 Case 3 sy(i) = Rnd(0) * 600 sx(i) = 599 End Select End Sub
sub quit H$ close #gr end end sub
sub pause mil 'tsh version has scan built-in t0 = time$("ms") while time$("ms") < t0 + mil : scan : wend end sub
'---------------------------------------------
function vect$(x,y) vect$=x;" ";y end function
function vectX(v$) vectX=val(word$(v$,1)) end function
function vectY(v$) vectY=val(word$(v$,2)) end function
function vectLen(v$) x=val(word$(v$,1)) y=val(word$(v$,2)) vectLen=sqr(x*x+y*y) end function
function vectUnit$(v$) x=val(word$(v$,1)) y=val(word$(v$,2)) vectLen=sqr(x*x+y*y) vectUnit$=x/vectLen;" ";y/vectLen end function
function vectAdd$(v1$,v2$) x1=val(word$(v1$,1)) y1=val(word$(v1$,2)) x2=val(word$(v2$,1)) y2=val(word$(v2$,2)) vectAdd$=x1+x2;" ";y1+y2 end function
function vectSub$(v1$,v2$) x1=val(word$(v1$,1)) y1=val(word$(v1$,2)) x2=val(word$(v2$,1)) y2=val(word$(v2$,2)) vectSub$=x1-x2;" ";y1-y2 end function
function vectDotProduct(v1$,v2$) x1=val(word$(v1$,1)) y1=val(word$(v1$,2)) x2=val(word$(v2$,1)) y2=val(word$(v2$,2)) vectDotProduct=x1*x2+y1*y2 end function
function vectScale$(a,v$) 'a * vector v$ x=val(word$(v$,1)) y=val(word$(v$,2)) vectScale$=a*x;" ";a*y end function
function vectTangent$(v$,base$) n$=vectUnit$(base$) vectTangent$=vectScale$(vectDotProduct(n$,v$),n$) end function
function vectNorm$(v$,base$) vectNorm$=vectSub$(v$,vectTangent$(v$,base$)) end function
function vectAngle(v$) x=val(word$(v$,1)) y=val(word$(v$,2)) vectAngle=atan2(y,x) end function
function vectFromPolar$(rho, phi) vectFromPolar$=rho*cos(phi);" ";rho*sin(phi) end function
function vectRotate$(v$,alpha) x=val(word$(v$,1)) y=val(word$(v$,2)) rho=sqr(x*x+y*y) phi=atan2(y,x)+alpha vectRotate$=rho*cos(phi);" ";rho*sin(phi) end function
function dePi$(x) 'pure aestetics 'dePi$=x/pi;"Pi" dePi$=using("##.###",x/pi);"Pi" 'place for sign end function
function normalizeAngle(x) x=x mod (2*pi) if x <0 then x=x+(2*pi) normalizeAngle = x end function
function dePiNorm$(x) 'pure aestetics 'norm z first x=x mod (2*pi) if x <0 then x=x+(2*pi) dePiNorm$=using("##.###",x/pi);"Pi" end function
'--------------------------- function atan2(y,x) 'pi = asn(1) * 2 'global if x <> 0 then arctan = atn(y/x)
select case case x > 0 atan2 = arctan
case y>=0 and x<0 atan2 = pi + arctan
case y<0 and x<0 atan2 = arctan - pi
case y>0 and x=0 atan2 = pi / 2
case y<0 and x=0 atan2 = pi / -2 end select end function
|
|
|
Post by plus on Feb 28, 2024 22:13:01 GMT
Rod's definitely a different approach, nice!
Tsh73 mine would look more like yours if I turn off the glitter effect:
global H$, XMAX, YMAX, nRing H$ = "gr" Xmax = 600 '<======================================== actual drawing space needed Ymax = 600 '<======================================== actual drawing space needed
nomainwin
WindowWidth = Xmax + 8 WindowHeight = Ymax + 32 UpperLeftX = (DisplayWidth - Xmax) / 2 'or delete if XMAX is 1200 or above UpperLeftY = (DisplayHeight - Ymax) / 2 'or delete if YMAX is 700 or above
open "Spinning Black Hole Attractor #3 = Ring O Stars" for graphics_nsb_nf as #gr #gr "trapclose quit" #gr "size 1" #gr "down" #gr "fill 60 0 30"
nstars = 60 Dim sx(nstars), sy(nstars), sr(nstars), sc$(nstars), tx(2000), ty(2000), tr(2000), tc$(2000) cx = 300: cy = 300 'setup start stars For i = 1 To nstars [tryagain] sx(i) = Rnd(0) * 600 sy(i) = Rnd(0) * 600 dx = cx - sx(i): dy = cy - sy(i) d = (dx * dx + dy * dy) ^ .5 if d <= 52 then goto [tryagain] sr(i) = Rnd(0) * 3 + 1 sc$(i) = rnd(0) * 128 + 128;" ";rnd(0) * 128 + 128;" ";rnd(0) * 128 + 128 Next Do #gr "fill 10 0 30" 'black Hole #gr "color 128 0 0" #gr "backcolor 0 0 0" #gr "place ";cx;" ";cy;"; circlefilled ";50 'show stars for i = 1 to nRing ' on Ring make glitter! 'if rnd(0) < .3*nRing/nRing then 'glit dx = cx - tx(i): dy = cy - ty(i) b = Atan2(dy, dx) d = (dx * dx + dy * dy) ^ .5 #gr "color ";tc$(i) #gr "backcolor ";tc$(i) #gr "place ";cx + d * cos(a + b);" ";cy + d * sin(a + b);"; circlefilled ";tr(i) 'end if next For i = 1 To nstars dx = cx - sx(i): dy = cy - sy(i) b = Atan2(dy, dx) d = (dx * dx + dy * dy) ^ .5 #gr "color ";sc$(i) #gr "backcolor ";sc$(i) #gr "place ";cx + d * cos(a + b);" ";cy + d * sin(a + b);"; circlefilled ";sr(i) 'now update stars falling into black hole dx = cx - sx(i): dy = cy - sy(i) d = (dx * dx + dy * dy) ^ .5 If d <= 53 Then 'black hole radius call newRing i call newStar i Else ' move it dx = 100 * dx / (d * d) dy = 100 * dy / (d * d) sx(i) = sx(i) + dx sy(i) = sy(i) + dy End If Next a = a + .006 call pause 60 Loop until something
sub newRing i nRing = nRing + 1 tx(nRing) = sx(i) ty(nRing) = sy(i) tr(nRing) = sr(i) tc$(nRing) = sc$(i) end sub
Sub newStar i r = Int(Rnd(0) * 4) ' 0 to 3 Select Case r Case 0 sx(i) = Rnd(0) * 600 sy(i) = 0 Case 1 sx(i) = Rnd(0) * 600 sy(i) = 599 Case 2 sy(i) = Rnd(0) * 600 sx(i) = 0 Case 3 sy(i) = Rnd(0) * 600 sx(i) = 599 End Select End Sub
sub quit H$ close #gr end end sub
sub pause mil 'tsh version has scan built-in t0 = time$("ms") while time$("ms") < t0 + mil : scan : wend end sub
Function Atan2(y, x) 'Atan2 is a function which determines the angle between points 'x1, y1 and x2, y2. The angle returned is in radians 'The angle returned is always in the range of '-PI to PI radians (-180 to 180 degrees) '============================================================== 'NOTE the position of Y and X arguments 'This keeps Atan2 function same as other language versions '============================================================== If x = 0 Then If y < 0 Then Atan2 = -1.5707963267948967 Else Atan2 = 1.5707963267948967 End If Else chk = atn(y/x) If x < 0 Then If y < 0 Then chk = chk - 3.1415926535897932 Else chk = chk + 3.1415926535897932 End If End If Atan2 = chk End If 'thanks Andy Amaya End Function
Now you can see the stars build up around the ring.
b = b + ...
|
|
|
Post by honky on Feb 29, 2024 9:19:26 GMT
In reality, after a few laps, the stars (and the rest) fall into the hole. Simple history becomes more complex.
In my opinion, there are not enough stars and too many big stars Maybe add fixed stars to relieve the processor (Those that are distant, Out of attraction, deep sky) .
|
|