Pomppivat planeetat ja vähän lukion fysiikkaa. Päivitetty 1.4.2004. Ohjelmassa lasketaan 2...6 planeetan kiertoradat ja liike näytetään 2D-animaationa sprite-tekniikkaa käyttäen. Kappaleiden liike perustuu painovoimaan, joka on verrannollinen massojen tuloon ja kääntäen verrannollinen etäisyyden neliöön. Tässä animaatiossa havaitaan selvästi, kuinka toinen planeetta voi lingota toisen huomattavasti korkeammalle radalle tai painovoiman ulottumattomiin. Tällä periaatteellahan käytetään esim. Marsia linkoamaan luotain kauemmaksi.
Laskennassa summataan enimmillään 5 voimavektoria. Summauksessa ei käytetä trigonometrisiä funktioita vaan yhdenmuotoisten kolmioiden suhteita. Näin laskenta nopeutuu.
Lomakkeella on Spritejä varten PictureBoxit picP(5), picM(5), picV(5) ja picZ (puskuri). Ohjetekstiä varten on tekstikehys lblO. Tämä näkyy käynnistyksen jälkeen sekä pysäytystilassa painamalla F1.
Liike käynnistyy painamalla SPACE.
Vihreä pallo on selvästi muita isompi ja emoplaneetta jota muut kiertävät. Reunapomput aiheuttavat pallojen törmäilyä eikä liikkeet vastaa enää planeettojen liikkeitä. Pallot noudattavat hyvin tarkasti fysiikan lakeja myös pompuissa. Voit säätää kimmoisuutta, Asettaa reunapomput päälle/pois ja vaihtaa keskinäisten vetovoimien tilalle painovoiman, jolloin pallot pomppivat kuin kumipallot. Mukana on myös ääniefektit. Tarvittavat äänitiedostot MCI-ohjaimen ja koko ohjelman voit ladata osoitteesta: http://personal.inet.fi/atk/korant/download.htm
'Pomppivat planeetat Antero Korteila 1.4.2004 ver. 4 'Pallot liikkuvat kuten aurinkokunnan planeetat noudattaen tarkasti 'Newtonin lakeja myös pompuissa. (2-ulotteisena !) Option Explicit Dim N As Integer 'planeettojen lukumäärä -1 (oletus 2) Dim Q As Byte 'tila Dim b(5) As Integer 'spriten leveys Dim r(5) As Single 'säteet Dim r1(5) As Single 'planeettojen säteet Dim r2(5) As Single 'pallojen säteet Dim r0 As Single 'säde Dim xx(5) As Double 'x-koord. Dim ex(5) As Double 'ed. x-koord. Dim yy(5) As Double 'y-koord. Dim ey(5) As Double 'ed. y-koord. Dim vx(5) As Double 'vaakanopeus Dim vy(5) As Double 'pystynopeus Dim m(5) As Double 'massat Dim e(5, 5) As Double 'etäisyydet Dim cP(5) As Long 'värit Dim cv(5) As Long 'värit nopeuden säädössä Dim xe(5) As Single, ye(5) As Single 'spriten edellinen x ja y Dim be(5) As Single 'spriten edellinen leveys Dim f(5, 5) As Double 'voima Dim fe(5, 5) As Double 'edellinen voima Dim dx(5, 5) As Double 'etäisyyden x-komp. Dim dy(5, 5) As Double 'etäisyyden y-komp. Dim I As Integer, J As Integer, k As Integer Dim MI As Integer, ek As Single, ra As Single Dim z As Long, x0 As Single, y0 As Single Dim kk As Single, nk As Integer, ns As Integer 'BitBlt-funktion määrittely Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long 'ohjeteksti Private Sub Form_Load() lblO = "NÄPPÄINKOMENNOT" + vbCrLf + _ vbCrLf + "ENTER = askel tai hidastettu ajo" + _ vbCrLf + "SPACE = käynnistys / pysäytys" + _ vbCrLf + "End = lopetus" + _ vbCrLf + "S = kiihdytä, s = hidasta sinistä" + _ vbCrLf + "P = kiihdytä, p = hidasta punaista" + _ vbCrLf + "C = ratojen putsaus" + vbCrLf + "R = reunapomput päälle / pois" + _ vbCrLf + "Q = painovoima / vetovoimat" + _ vbCrLf + "K/k = kimmoisuus +/- (0,1...0,99)" + _ vbCrLf + "n = uusi aloitus, keskusplaneetan koko vaihtelee" + _ vbCrLf + "Nuolinäpp. keskustan siirto valittuun suuntaan" + _ vbCrLf + "Numeroilla 1...5 kiertävien planeettojen määrä" + _ vbCrLf + "Pysäytystilassa voit muuttaa planeetan" + _ vbCrLf + "sijaintia, kokoa tai nopeutta seuraavasti:" + _ vbCrLf + "Valitse planeetta Numpadistä numerolla 0...5" + _ vbCrLf + "Hiiren vasemmalla paikka ja koko," + _ vbCrLf + "oikealla nopeus ja suunta," + _ vbCrLf + " (ympyrän säde osoittaa nopeutta," + _ vbCrLf + " jolla rata on ympyrä)" N = 5 'värit cP(2) = &HE0 'ratojen värit cP(1) = &HE00000 cP(0) = &HA000& cP(3) = &HA0A0&: cP(4) = &HFF00E0: cP(5) = &HB0B000 cv(2) = &HFF 'nopeusvektorin väri cv(1) = &HFF0000 cv(3) = &HFFFF&: cv(4) = &HFF00FF: cv(5) = &HFFFF00 Randomize r(2) = 12: r(1) = 10: r(0) = 45 + 20 * Rnd 'säteet r(3) = 14: r(4) = 12: r(5) = 16 r2(2) = 32: r2(1) = 20 'säteet r2(3) = 28: r2(4) = 42: r2(5) = 36 ra = 45 / Atn(1) 'radiaanit asteiksi kk = 0.85 'kimmokerroin End Sub 'lähtötilanne Private Sub Form_Resize() Static tila As Boolean If tila Then tila = False: Exit Sub If WindowState = 1 Then tila = True: Exit Sub Dim b As Single Dim x As Single, y As Single x0 = Me.ScaleWidth * 0.5 'keskipiste y0 = Me.ScaleHeight * 0.5 xx(1) = x0 * 0.8 xx(2) = x0 * 1.4 'x-koordinaatit xx(3) = x0 * 0.4 xx(4) = x0 * 1.75 xx(5) = x0 * 0.1 For I = 0 To 5 yy(I) = y0 'y-koordinaatit m(I) = r(I) ^ 3 'massa = r^3 pallo I Next 'pallojen painopiste keskelle emo picZ.Width = Me.ScaleWidth 'puskurin koko ja paikka picZ.Height = Me.ScaleHeight picZ.Top = picZ.Height 'taustalle hiusviivat viivat For I = 0 To N 'pallojen blittaus If I > 0 Then nopeus I 'If I = 2 Or I = 4 Then vy(I) = -vy(I) x = xx(I) - r(I): y = yy(I) - r(I) b = 2 * r(I) + 1 'otetaan kuva talteen z = BitBlt(picV(I).hDC, 0, 0, b, b, picZ.hDC, x, y, vbSrcCopy) xe(I) = x: ye(I) = y: be(I) = b Next DoEvents blit lblO.Visible = True Q = 8 End Sub
'näppäinohjaukset Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer) Dim b As Single Dim x As Single, y As Single Dim dx As Integer, dy As Integer Select Case KeyCode Case vbKeyEnd End 'lopetus Case vbKeyF1 lblO.Visible = True 'ohje näkyviin Case vbKeyReturn Q = Q + 1 - (Q And 1) 'startti If (Q And 8) = 0 Then For I = 0 To N vx(I) = 0.5 * (Rnd - 0.5) vy(I) = -0.5 * Rnd + 0.2 Next End If liike tausta Case vbKeySpace Q = Q + 1 - 2 * (Q And 1): liike 'stop / run Timer1.Enabled = -(Q And 1) lblO.Visible = False Case vbKeyR Q = Q + 16 - 2 * (Q And 16) 'reunapomppu päälle / pois 'eli B:n viides bitti 1 tai 0 Case vbKeyQ 'keskinäiset vetovoimat / painovoima If (Q And 8) Then 'vetovoimat pois, painovoima tilalle Q = Q - 8 Q = Q + 16 - (Q And 16) 'reunapomppu päälle For k = 1 To 5 r1(k) = r(k) r(k) = r2(k) m(k) = r(k) ^ 3 pallo k x = xx(k) - r(k): y = yy(k) - r(k) b = 2 * r(k) + 1 'otetaan kuva talteen z = BitBlt(picV(k).hDC, 0, 0, b, b, picZ.hDC, x, y, vbSrcCopy) xe(k) = x: ye(k) = y: be(k) = b Next picZ.Picture = LoadPicture("") 'tyhjätään tausta tausta Else For k = 1 To 5 r2(k) = r(k) r(k) = r1(k) m(k) = r(k) ^ 3 pallo k x = xx(k) - r(k): y = yy(k) - r(k) b = 2 * r(k) + 1 'otetaan kuva talteen z = BitBlt(picV(k).hDC, 0, 0, b, b, picZ.hDC, x, y, vbSrcCopy) xe(k) = x: ye(k) = y: be(k) = b Next Q = Q + 8 tausta End If Case vbKeyP, vbKeyS I = 2: If KeyCode = vbKeyS Then I = 1 If Shift = 1 Then vx(0) = vx(0) - m(I) * vx(I) * 0.02 / m(0) 'liikemäärän tasaus vy(0) = vy(0) - m(I) * vy(I) * 0.02 / m(0) vx(I) = vx(I) * 1.02 ' kiihdytys vy(I) = vy(I) * 1.02 Else vx(0) = vx(0) + m(I) * vx(I) * 0.02 / m(0) 'liikemäärän tasaus vy(0) = vy(0) + m(I) * vy(I) * 0.02 / m(0) vx(I) = vx(I) * 0.98 ' hidastus vy(I) = vy(I) * 0.98 End If Case vbKeyC tausta 'kiertoratojen putsaus Case vbKeyK If Shift = 1 Then 'kimmokerroin kk = kk * 1.01: If kk > 0.99 Then kk = 0.99 Else kk = kk * 0.99: If kk < 0.1 Then kk = 0.1 End If ns = 1: nk = 200 Case vbKeyN r(0) = 45 + 20 * Rnd m(0) = r(0) ^ 3 Form_Resize Case vbKey1 To vbKey5 For I = N To KeyCode - 48 pallo I nopeus I Next N = KeyCode - 48 Case vbKeyNumpad0 To vbKeyNumpad5 I = KeyCode - 96 If Q And 1 Then Else If (Q And 4) = 0 Then Q = Q + 4 End If Case vbKeyLeft dx = 5 * (x0 > 0) 'keskustan siirto vasemmalle GoSub siirto Case vbKeyRight dx = -5 * (x0 < Me.ScaleWidth) 'siirto oikealle GoSub siirto Case vbKeyUp dy = 5 * (y0 > 0) 'siirto ylös GoSub siirto Case vbKeyDown dy = -5 * (y0 < Me.ScaleHeight) 'siirto alas GoSub siirto End Select Exit Sub siirto: x0 = x0 + dx: y0 = y0 + dy For I = 0 To N xx(I) = xx(I) + dx yy(I) = yy(I) + dy Next viivat tausta End Sub 'hiiriohjaukset Private Sub Form_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single) If (Q And 1) Or (Q And 4) = 0 Then Exit Sub 'jos liikkeellä, ei sallita If Button = 1 Then xx(I) = x: yy(I) = y 'vihreä hiirikohdistimeen lblN = Str(Int(Sqr((x - x0) ^ 2 + (y - y0) ^ 2) * 3 + 0.5) / 100) + " cm" lblN.Left = x: lblN.Top = y - lblN.Height lblN.Visible = True r0 = r(I) If (Q And 8) Then If I > 0 Then 'emopallon paikka niin, emo 'että painopiste on keskellä End If viivat End If blit ElseIf Button = 2 And I > 0 Then asnop 'apuviiva ja ympyrä End If End Sub 'planeetan säteen tai nopeuden säätö Private Sub Form_MouseMove(Button As Integer, Shift As Integer, x As Single, y As Single) Static ex As Single, ey As Single Dim xu As Single, yu As Single If (Q And 1) = 1 Or (Q And 4) = 0 Then Exit Sub If Button = 1 Then 'säteen säätö 'säde vähintään 3 (vihreällä 10) If r(I) + (x - xx(I)) / 4 < 3 - 8 * (I = 0) Then Exit Sub r(I) = r0 + (x - xx(I)) / 4 m(I) = r(I) ^ 3 If Q And 8 Then emo xu = xx(I) - r(I): yu = yy(I) - r(I) 'palautetaan taustat z = BitBlt(picZ.hDC, xe(I), ye(I), be(I), be(I), picV(I).hDC, 0, 0, vbSrcCopy) pallo I 'otetaan kuvat talteen z = BitBlt(picV(I).hDC, 0, 0, b(I), b(I), picZ.hDC, xu, yu, vbSrcCopy) xe(I) = xu: ye(I) = yu: be(I) = b(I) blit ElseIf Button = 2 Then 'nopeuden säätö If DrawMode = 7 Then Line (xx(I), yy(I))-(ex, ey), cv(I) Else DrawMode = 7 End If Line (xx(I), yy(I))-(x, y), cv(I) ex = x: ey = y End If End Sub 'nopeuden laskenta tai asetus Private Sub Form_MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single) If (Q And 1) Or (Q And 4) = 0 Then Exit Sub If Button = 1 Then m(I) = r(I) ^ 3 If Q And 8 Then For I = 0 To N nopeus I 'lasketaan ympyrärataa vastaava nopeus Next viivat tausta End If blit ElseIf Button = 2 And I > 0 Then vx(I) = (x - xx(I)) / 5000 vy(I) = (y - yy(I)) / 5000 If Q And 8 Then nopeus 0 DrawMode = 13 picZ.Cls blit End If Q = Q - 4 End Sub
Sub liike() Dim ax(5) As Double, ay(5) As Double 'kiihtyvyydet Dim a0 As Double, a1 As Double 'apumuuttujat Dim v As Double, fn As String 'nopeus Dim xk As Single, yk As Single Dim ak As Single, sk As Single For k = 1 To 100 voimat 'etäisyydet For I = 0 To N - 1 For J = I + 1 To N e(I, J) = Sqr(e(I, J)) If e(I, J) < r(I) + r(J) Then 'kosketus pomppu End If Next ax(I) = 0: ay(I) = 0 Next ax(I) = 0: ay(I) = 0 If 8 And Q Then 'vetovoimat For I = 0 To N - 1 For J = I + 1 To N a0 = f(I, J) / e(I, J): a1 = a0 * dx(I, J) ax(I) = ax(I) - a1: ax(J) = ax(J) + a1 a1 = a0 * dy(I, J) ay(I) = ay(I) - a1: ay(J) = ay(J) + a1 Next Next Else 'painovoima For I = 0 To N ay(I) = 0.00001 * m(I) Next End If For I = 0 To N ax(I) = ax(I) / m(I) ay(I) = ay(I) / m(I) vx(I) = vx(I) + ax(I) vy(I) = vy(I) + ay(I) ex(I) = xx(I) xx(I) = ex(I) + vx(I) - ax(I) / 2 ey(I) = yy(I) yy(I) = ey(I) + vy(I) - ay(I) / 2 If Q And 16 Then 'pomput reunoista If xx(I) < r(I) Then fn = "LAP11.WAV" If vx(I) > -0.05 / (2 + (Q And 8)) Then GoTo ohi ElseIf vx(I) > -0.2 / (2 + (Q And 8)) Then Mid(fn, 4, 1) = "5" ElseIf vx(I) > -0.5 / (2 + (Q And 8)) Then Mid(fn, 4, 1) = "3" End If MMC(I).filename = fn MMC(I).Command = "Open" MMC(I).Wait = False MMC(I).Command = "Sound" ohi: sk = Sqr(kk) xx(I) = 2 * r(I) - xx(I) vx(I) = -vx(I) * sk: vy(I) = vy(I) * sk ElseIf xx(I) > ScaleWidth - r(I) Then fn = "LAP14.WAV" If vx(I) < 0.02 / (2 + (Q And 8)) Then GoTo ohi0 ElseIf vx(I) < 0.2 / (2 + (Q And 8)) Then Mid(fn, 4, 1) = "5" ElseIf vx(I) < 0.5 / (2 + (Q And 8)) Then Mid(fn, 4, 1) = "3" End If MMC(I).filename = fn MMC(I).Command = "Open" MMC(I).Wait = False MMC(I).Command = "Sound" ohi0: sk = Sqr(kk) xx(I) = 2 * (ScaleWidth - r(I)) - xx(I) vx(I) = -vx(I) * sk: vy(I) = vy(I) * sk End If If yy(I) < r(I) Then sk = Sqr(kk) yy(I) = 2 * r(I) - yy(I) vy(I) = -vy(I) * sk: vx(I) = vx(I) * sk Select Case Abs(vy(I)) Case Is > 1 / (2 + (Q And 8)) MMC(I).filename = "LAP1.WAV" Case Is > 0.5 / (2 + (Q And 8)) MMC(I).filename = "LAP2.WAV" Case Is > 0.2 / (2 + (Q And 8)) MMC(I).filename = "LAP3.WAV" Case Is > 0.1 / (2 + (Q And 8)) MMC(I).filename = "LAP4.WAV" Case Is > 0.02 / (2 + (Q And 8)) MMC(I).filename = "LAP5.WAV" Case Else GoTo ohi1 End Select MMC(I).Command = "Open" MMC(I).Wait = False MMC(I).Command = "Sound" ohi1: ElseIf yy(I) > ScaleHeight - r(I) Then sk = Sqr(kk): If Abs(vy(I)) < 0.002 Then sk = 1 - kk / 5000 yy(I) = 2 * (ScaleHeight - r(I)) - yy(I) vy(I) = -vy(I) * sk: vx(I) = vx(I) * sk Select Case Abs(vy(I)) Case Is > 1 / (2 + (Q And 8)) MMC(I).filename = "LAP1.WAV" Case Is > 0.5 / (2 + (Q And 8)) MMC(I).filename = "LAP2.WAV" Case Is > 0.2 / (2 + (Q And 8)) MMC(I).filename = "LAP3.WAV" Case Is > 0.1 / (2 + (Q And 8)) MMC(I).filename = "LAP4.WAV" Case Is > 0.05 / (2 + (Q And 8)) MMC(I).filename = "LAP5.WAV" Case Is < 0.01 yy(I) = ScaleHeight - r(I) If Abs(vy(I)) < 0.002 Then vy(I) = 0 GoTo ohi2 End Select MMC(I).Command = "Open" MMC(I).Wait = False MMC(I).Command = "Sound" ohi2: End If End If Next Next blit CurrentY = 0 Select Case ns Case 1 CurrentX = ScaleWidth - 100 Print "k = "; Format(kk, "0.###") nk = nk - 1: If nk = 0 Then ns = 0 End Select If (8 And Q) = 0 Then Exit Sub For I = 1 To N If e(0, I) > ScaleWidth * 0.5 Then CurrentX = ScaleWidth - 100 xk = xx(I) - ScaleWidth / 2 yk = yy(I) - ScaleHeight / 2 ek = Sqr(xk * xk + yk * yk) / 34 If xk = 0 Then ak = 90 Else ak = Atn(-yk / xk) * ra If xk < 0 Then ak = ak + 180 Print I; " "; Format(ek, "###.0"); " "; Format(ak, "###°") End If Next End Sub Sub voimat() For I = 0 To N - 1 For J = I + 1 To N dx(I, J) = xx(I) + vx(I) / 2 - xx(J) - vx(J) / 2 'vaaka- ja pystyetäisyydet dy(I, J) = yy(I) + vy(I) / 2 - yy(J) - vy(J) / 2 e(I, J) = dx(I, J) * dx(I, J) + dy(I, J) * dy(I, J) 'etäisyyden neliöt f(I, J) = m(I) * m(J) / e(I, J) / 1000000 'vetovoimat Next Next 'nopeuden puolisko parantaa laskentatarkkuutta 'vakio määrätty kokeellisesti End Sub
'emopallon paikka siten, että yhteinen painopiste on keskellä Sub emo() xx(0) = (x0 - xx(1)) * m(1) yy(0) = (y0 - yy(1)) * m(1) For J = 2 To N xx(0) = xx(0) + (x0 - xx(J)) * m(J) yy(0) = yy(0) + (y0 - yy(J)) * m(J) Next xx(0) = xx(0) / m(0) + x0 yy(0) = yy(0) / m(0) + y0 End Sub 'nopeuden asettelu Sub asnop() 'piirretään ympyrärataa vastaava nopeus viivana ja ympyränä Line (xx(I), yy(I))-Step(5000 * vx(I), 5000 * vy(I)) Circle (xx(I), yy(I)), 5000 * Sqr(vx(I) * vx(I) + vy(I) * vy(I)) End Sub 'boxien koko ja pallon piirto Sub pallo(I As Integer) Dim d As Single, rd As Single Dim xd As Single, cc As Long Dim g(2) As Long, c(2) As Byte cc = cP(I) For J = 0 To 2 g(J) = 255 And cc cc = (cc - g(J)) \ 256 g(J) = g(J) * 0.7 Next b(I) = 2 * r(I) + 1 picP(I).Width = b(I) picP(I).Height = b(I) picP(I).Cls picM(I).Width = b(I) picM(I).Height = b(I) picM(I).Cls picV(I).Width = b(I) picV(I).Height = b(I) picV(I).Cls For d = 0 To 250 Step 0.6 + 50 / r(I) 'piirretään täytetty pallo, rd = r(I) * (250 - d) / 251 'jonka täyttö vaalenee asteittain xd = 0.6 * r(I) + 0.4 * rd 'ja antaa 3D-vaikutelman For J = 0 To 2 c(J) = g(J) + (255 - g(J)) * d / 255 Next picP(I).Circle (xd, xd), rd, RGB(c(0), c(1), c(2)) If d = 0 Then picM(I).Circle (xd, xd), rd 'piirretään maski Next End Sub 'pallojen kosketuksessa täysin kimmoinen pomppu Sub pomppu() Dim k As Double, p As Double, s As Double 'apumuuttujia Dim lm As Double, le As Double 'liikemäärä, liike-energia Dim lm1 As Double, lm2 As Double Dim d As Double, xd As Double, yd As Double 'etäisyys ja sen x- ja y-komp. Dim v1 As Double, v2 As Double 'kohtausnopeus Dim s1 As Double, s2 As Double 'sivuttaisnopeus (ei muutu) 'etäisyys ja sen vaaka- ja pystykomponentit d = e(I, J): xd = xx(J) - xx(I): yd = yy(J) - yy(I) v1 = (vx(I) * xd + vy(I) * yd) / d 'kohtisuorat nopeudet v2 = (vx(J) * xd + vy(J) * yd) / d s1 = (vx(I) * yd - vy(I) * xd) / d 'sivuttaisnopeudet (eivät muutu) s2 = (vx(J) * yd - vy(J) * xd) / d Select Case Abs(v1 - v2) Case Is > 1 / (2 + (Q And 8)) MMC(I).filename = "POP1.WAV" Case Is > 0.7 / (2 + (Q And 8)) MMC(I).filename = "POP2.WAV" Case Is > 0.5 / (2 + (Q And 8)) MMC(I).filename = "POP3.WAV" Case Is > 0.2 / (2 + (Q And 8)) MMC(I).filename = "POP4.WAV" Case Is > 0.1 / (2 + (Q And 8)) MMC(I).filename = "POP5.WAV" Case Else GoTo ohi End Select MMC(I).Command = "Open" MMC(I).Wait = False MMC(I).Command = "Sound" ohi: lm1 = v1 * m(I): lm2 = v2 * m(J) lm = lm1 + lm2 'liikemäärä le = (v1 * lm1 + v2 * lm2) * kk 'liike-energia k = m(I) + m(J) p = lm / k: s = (lm * lm - le * m(J)) / m(I) / k On Error Resume Next lm2 = Sqr(Abs(p * p - s)) 'toisen asteen yhtälön ratkaisu v1 = p - lm2: v2 = (lm - v1 * m(I)) / m(J) v1 = v1 / (1 + v1 * v1): v2 = v2 / (1 + v2 * v2) 'vaimennus vx(I) = (v1 * xd + s1 * yd) / d 'törmäyksen jälkeiset nopeudet vx(J) = (v2 * xd + s2 * yd) / d vy(I) = (v1 * yd - s1 * xd) / d vy(J) = (v2 * yd - s2 * xd) / d End Sub 'spritet Sub blit() Dim d As Single, rd As Single Dim xd As Single, yd As Single, c(5) As Byte Dim z As Long, b(5) As Single Dim x(5) As Single, y(5) As Single Dim I As Integer For I = 0 To N x(I) = xx(I) - r(I): y(I) = yy(I) - r(I) b(I) = 2 * r(I) + 1 'palautetaan taustat z = BitBlt(picZ.hDC, xe(I), ye(I), be(I), be(I), picV(I).hDC, 0, 0, vbSrcCopy) Next 'plotataan keskipisteet For I = 0 To N picZ.PSet (xx(I), yy(I)), cP(I) Next For I = 0 To N 'otetaan kuvat talteen z = BitBlt(picV(I).hDC, 0, 0, b(I), b(I), picZ.hDC, x(I), y(I), vbSrcCopy) Next For I = 0 To N 'piirretään spritet z = BitBlt(picZ.hDC, x(I), y(I), b(I), b(I), picM(I).hDC, 0, 0, vbSrcAnd) z = BitBlt(picZ.hDC, x(I), y(I), b(I), b(I), picP(I).hDC, 0, 0, vbSrcInvert) xe(I) = x(I): ye(I) = y(I) Next 'kuva puskurista formille z = BitBlt(Me.hDC, 0, 0, picZ.Width, picZ.Height, picZ.hDC, 0, 0, vbSrcCopy) End Sub 'taustan putsaus Sub tausta() picZ.Cls For I = 0 To N picV(I).Cls 'otetaan kuvat talteen z = BitBlt(picV(I).hDC, 0, 0, be(I), be(I), picZ.hDC, xe(I), ye(I), vbSrcCopy) Next End Sub 'ympyrärataa vastaava nopeus Sub nopeus(I As Integer) Dim v As Single, e As Single 'lähtönopeus ja -etäisyys Dim dx As Single, dy As Single 'etäisyyden x- ja y-komp. If I > 0 Then dx = xx(I) - xx(0) dy = yy(I) - yy(0) e = Sqr(dx ^ 2 + dy ^ 2) v = Sqr(m(0) / e / (1 + m(I) / m(0))) / 1000 vx(I) = -dy * v / e: vy(I) = dx * v / e End If 'vihreän pallon nopeus, jolla kokonaisliikemäärä = 0 'jolloin systeemin painopiste pysyy paikallaan vx(0) = 0: vy(0) = 0 For J = 1 To N vx(0) = vx(0) - vx(J) * m(J) vy(0) = vy(0) - vy(J) * m(J) Next vx(0) = vx(0) / m(0): vy(0) = vy(0) / m(0) End Sub 'piirretään ristikko pysyväksi Sub viivat() picZ.Picture = LoadPicture("") picZ.Line (x0, 0)-(x0, picZ.Height), &H808080 picZ.Line (0, y0)-(picZ.Width, y0), &H808080 For J = 1 To N picZ.Circle (x0, y0), Sqr((x0 - xx(J)) ^ 2 + (y0 - yy(J)) ^ 2), &H808080 Next picZ.Picture = picZ.Image End Sub Private Sub Form_Unload(Cancel As Integer) End End Sub Private Sub Timer1_Timer() liike End Sub
Selkeää koodia, mutta EXEä kaipaillaan :)
Kuulostaa hienolta. Hienoa koodia. Mutta onko EXEä?
Hieno! Ei voi muuta sanoa. Nuo "pallot" muuten sekoaa vähän ajan päästä.
Onko Ohjelmointiputkassa paikkaa noille exeille ??
Muutin hiukan lähtöarvoja ja asetuksia. nyt pitäisi toimia VB5:llä ja VB6:lla ainakin.
Hyvin toimii. Aika hyvää jälkeä tulee, kun sitä isointa planeettaa lähtee liikkuttamaan.
No ny voi exet imuttaa osoitteesta:
http://personal.inet.fi/atk/korant/download.htm
Tuo exe on huomattavasti nopeampi ja muutinkin vihreän pallukan pienemmäksi, joka hidastaa vauhtia.
Lisää palloja! :D
Ainut joka oli outoo, oli se että pallot nopeutuu mitä isomman pallon ympärillä ne pyörii.
Miten tohon sais lisää palloja? 20 palloo olis kiva :)
Kolmella pallolla on laskettava jokaiselle voimavaikutus kahteen muuhun, neljällä vastaavasti kolmeen muuhun jne. Pallojen määrän kasvaessa tarvittava laskentateho kasvaa jyrkästi.
Kiertonopeus noudattaa Newtonin lakeja, ja nehän ovat edelleen voimassa erittäin suurella tarkkuudella. Jos vihreän pallon läpimitta kaksinkertaistuu, sen massa kasvaa 8-kertaiseksi ja kiertonopeuden neliö 8-kertaiseksi eli nopeus lähes kolmin kertaiseksi.
Mutta eihän planeetatkaan liiku auringon ympärillä nopeammin mitä lähempänä ne ovat? :P
Ainakaan niin nopeasti kuin tuossa ohjelmassa :D
Aika hassu tuo ohjelma oli silti, ihan kuin leikkisi magneeteilla :)
Kyllä ne vaan liikkuvat. Katso jostain tietokirjasta, mikä on esim. Marsin vuosi tai Venuksen vuosi. Pallojen välillä vaikuttaa vetovoima (painovoima). Tässä animaatiossa kierrosajat ovat vaan sekunnin suuruusluokkaa vuoden sijasta. Tokko kukaan viitsisi vahdata vuositolkulla pallon liikettä. Muuttamalla pallojen etäisyyksiä ja kokoa saa lukemattomia eri versioita liikeradoista. Animaatio osoittaa selvästi sen, miksi planeettojen radat "elävät" eli muuttuvat jatkuvasti toistensa vetovoiman vaikutuksesta.
Marsin ja Venuksen vuosien pituus erothan johtuvat siitä, että niillä on lyhyempi kiertorata? :P
Hmm... toi uus versio ei toiminut :( Tulee joku runtime error '9'
No jopas, nyt toimii! Tosi hieno on :-o
Eräs pikkuseikka vain, että toi hidastaa windowsin toimintoja, eli wintoosa reagoi näppäimistön paineluihin ym muutaman sekunnin viivelllä :P
Olis kiva saada tohon monta monta monta palloa lisää :)
ja sitten noi piirtobugit pois ym.
Tosi hieno :O
Painovoimahan on kääntäen verrannollinen etäisyyteen eli ~1/r². Nopeus, jolla planeetta pysyy ympyräradalla eli keskipakovoima kumoaa painovoiman (keskeiskiihtyvyys = painovoiman kiihtyvyys) saadaan kaavasta voima ~v²/r. Tästä seuraa, että nopeus v ~ 1/sqr(r) siis kääntäen verrannollinen etäisyyden neliöjuureen. Jos kiertoradan säde nelinkertaistuu, nopeus putoaa puoleen ja kiertoaika 1/8-osaan. Näin tosiaan tuossa animaatiosa käy. Ratojen laskenta perustuu pelkästään pallojen välisiin voimavaikutuksiin, jotka ovat verrannollisia massojen tuloon ja kääntäen verrannollisia etäisyyden neliöön. Voimat antavat palloille tietyn kiihtyvyyden, sen perusteella lasketaan nopeus ja edelleen nopeuden perusteella paikka. Tuossa laskennassa tarvitaan vähän geometriaakin.
Piirtobugit johtuvat tuosta sprite-tekniikasta. Kun pläjäytetään useampi sprite peräkkäin, ei läpinäkyvyys olekkaan joka tilanteessa läpinäkyvä. Tämä on ensimmäinen kerta, kun spritejä käytän ja paljon tuli yllättävää vastaan. Antti teki tuon spriteoppaan ja ehkä tietäisi syyn piirtobugeihin.
Pallojahan voi kyllä lisätä rajatta mutta wintoosa hidastuu silloin tosi pahasti. Mulla mylly jauhaa näillä kolmellakin 100% teholla kun planeetat pyörii. Ajastimella voisi aikaa järjestyä muihin hommiin mutta silloin piirto taas hidastuu. Tää oli nyt vähän pitkä juttu, mutta ihan kiva että aihe kiinnostaa. Itse olen juuri kiinnostunut mallintamaan erilaisia fysiikan ja mekaniikan ilmiöitä VB:llä. Muita kieliä kun en osaa.
Siis ekarivillä piti olla kääntäen verrannollinen etäisyyden neliöön kuten kaavassakin on
No voi hemmetti kun mä bugailen eikä noita kommentteja voi muokata. Tottakai tossa piti olla, että kierrosaika kasvaa 8-kertaiseksi
Tässä näköjään nyt vaan itselleni vastailen. Spriten piirto toimii nyt virheettömästi. Asiat piti vaan tehdä oikeassa järjestyksessä. Päivitän koodivinkkeihin myös korjatun version. Samalla meni koko hoito hitaammaksi. Myös tuo virheellinen exe. Eli koneen nopeus vaihtelee älyttömästi. Outoa.
Tossa sun tiedoston latausosoitteessa on jotain pahasti vialla, piti painaa sitä latausta n. 5 kertaa kunnes se tuli koneelle :|
HMM... nyt on jossain pahasti vialla, nimittäin tuo on nyt todella hidas :(
Joo, jotain outoa on. Nihkeästi pyörii alussa ja prossukäyttöä lähes 60%. Kun poistan Nortonin Securityn käytöstäja Quick Timen kuvakkeen niin Plan.exeä voi pyörittää jouhevasti neljäkin kappaletta ja prossun käyttöaste on noin 10%. Siis yksi ohjelma vie vain noin pari % prossun tehoa.
ei toimi... miten nuo pictureboxit? (2)-kohtaa ei voi laittaa nimeksi.
Näyttää kuvan Windowsin tilarivistä
... miten nuo pictureboxit? (2)-kohtaa ei voi laittaa nimeksi.
Suluissa on suurin indeksi. Nyt indeksointi on 0...5 eli 6 kpl kutakin. Ohjaimen nimi ilman indeksiä!
Ei toiminu. Tuli Error list:in mukaan 102 virhettä. En tiedä...
Aihe on jo aika vanha, joten et voi enää vastata siihen.