0 svar
81 visningar
jonasJ behöver inte mer hjälp
jonasJ 77
Postad: 27 maj 20:27 Redigerad: 27 maj 20:34

Fysiksimulator av protoner - Oönskad beteende i funktion

Observera att detta är en lång tråd med rätt så mycket information. Jag har mycket att säga och förklara. Jag hinner nog inte att besvara något just idag men jag kan läsa alla inlägg imorgon.

Sedan igår började att programmera ett projekt som jag nu ska dela med mig. Detta är inte ett skolprojekt utan jag tog själv initiativet att påbörja detta projekt. Men detta program berör främst fysiken, dvs. kursen Fysik 1 som jag just nu läser. Jag har stött på ett problem i min kod som orsakar ett upprepande fel och därav ett oönskat beteende.

Den senaste perioden som jag programmerade med javascript var i 9:an då vi använde det för att göra skolprojekt. Det vill säga, jag är lite rostig på att skriva med javascript och det är mycket som jag har börjat komma ihåg, både idag och igår. Främst av allt har jag behövt snabbt dyka igenom listor då de är absolut krävande för detta projekt. Jag är inte alls van med listor och jag tror att problemet ligger i en av uttrycken som behandlar två stycken listor för att göra en uträkning.

Eftersom att jag inte har skrivit med javascript sedan 9:an så använder jag också samma program från 9:an. Dvs. en websida som kallas för spelprogrammering, specifikt koda.nu/labbet. Jag har nyss upptäckt ett annat mer hjälpsamt webprogram som är JS Bin som också använder javascript och har debugging verktyg. Jag har vanligtvis inte åtkomst till några sådana verktyg i min browser eftersom att detta projekt görs på min skoldator. 

 

Notera att jag har inte gjort en utförlig formel över protonernas riktning då de knuffas, bara den skalära accelerationen med en riktning som går mot nedre högra hörnet av skärmen.

Här är följande program med den senaste versionen som jag har skrivit;

 

Som länk i koda.nu; https://koda.nu/labbet/40782473

 

Eller i spoilern nedanför;

Visa spoiler - programmets kod
<script src="https://koda.nu/simple.js">

  
  
  //Variabler
  var tidstal = 0
  
  var z = 5 //Antal protoner i hela programmet, ändra för att får mer eller färre protoner
  
  var vecx = 9 //Vecx betonar hastighetspilen som visas på protonerna
  var compx = 20 //Compx betonar och kompenserar extra för accelerationspilen som visas på protonerna
  
  //Förberedningskod
  var protoner = [];
  
  var p = 0
  
  while (p < z) //Skapar protonerna som används i huvudkoden
  {
    protoner.push({x: random(totalWidth),
                   y: random(totalHeight),
                   mass: (1),//1.67E-27
                   xvel: random(-3,3),
                   yvel: random(-3,3),
                   xac0: random(-0.01,0.01),
                   yac0: random(-0.01,0.01),
                   xac: 0,
                   yac: 0,
                   radius: 10,
                   number: (p+1)})
    p += 1
  }
  
  
  //Huvudkod
  function update()
  {
    clearScreen()
    
    tidstal += 1 //Visar hur många uppdateringar som har skett, inte viktig i uträkning
    
    var p = 0;
    
    while(p < z)
    {
      var proton = protoner[p]; //Detta är listan av protoner som utför i princip alla aspekter av rörelse, variabeln p bestämmer vilken proton som är vald utav z antal protoner
      
      circle(proton.x, proton.y, proton.radius, "Red")
      
      p += 1;

      
      var p0 = 0;
      
      while (p0 < z)
      {
        var proton0 = protoner[p0]; //Det här är alla protoner förutom den utvalda protonen av proton[p], de här protonerna finns för uträkningen i följande uttryck nedan
        
              
        if (proton != proton0) //HÄR är problemet, eller i alla fall vart jag anar att det kan vara. Detta uttryck fungerar inte som det ska - se utvecklad förklaring i inlägget
        {
          proton.xac = proton.xac0 + 1/distance(proton.x, proton.y, proton0.x, proton0.y);
          proton.yac = proton.yac0 + 1/distance(proton.x, proton.y, proton0.x, proton0.y);    
        }
        
        p0 += 1;
      }
      
      if (keyboard.space)
      { //Specialinformation om vardera proton, ber om ursäkt ifall det kan bli svårt att se, tryck på spacebar för att öppna.
        text((proton.x-3), (proton.y+3), 9, proton.number, "White")
        text((proton.x - 57), (proton.y + 23), 8, ("Position; " + "X:"+(proton.x).toFixed(2)+" Y:"+(proton.y).toFixed(2)), "Black")
        text((proton.x - 57), (proton.y + 35), 8, ("Velocity; " + "X:"+(proton.xvel).toFixed(2)+" Y:"+(proton.yvel).toFixed(2)), "Black")
        text((proton.x - 57), (proton.y + 46), 8, ("Acceleration; " + "X:"+(proton.xac).toFixed(4)+" Y:"+(proton.yac).toFixed(4)), "Black")
        line(proton.x, proton.y, (proton.x + proton.xvel*vecx), (proton.y + proton.yvel*vecx), 1, "Green") //Hastighetspil, tun och grön
        line(proton.x, proton.y, (proton.x + proton.xac*vecx*compx), (proton.y + proton.yac*vecx*compx), 5, "Yellow") //Accelerationspil, bred och gul
      }
      
      //Låter spelaren accelera alla protoner mot valfri riktning, använd piltangenterna
      if (keyboard.up)
        proton.yac0 -= 0.001
        
      if (keyboard.down)
        proton.yac0 += 0.001
        
      if (keyboard.left)
        proton.xac0 -= 0.001
        
      if (keyboard.right)
        proton.xac0 += 0.001
        
      //Behandlar acceleration, hastighet och position
      proton.xvel += proton.xac
      proton.yvel += proton.yac
      
      proton.x += proton.xvel
      proton.y += proton.yvel
      
      
      //De följande fyra uttrycken ser till att protonerna inte flyger ut ur vy och istället studsar på väggarna.
      if (proton.x > totalWidth)
      {
        proton.x -= 1
        proton.xvel *= -1
        proton.xac0 = 0
      }
      
      if (proton.x < 0)
      {
        proton.x += 1
        proton.xvel *= -1
        proton.xac0 = 0
      }
      
      if (proton.y > totalHeight)
      {
        proton.y -= 1
        proton.yvel *= -1
        proton.yac0 = 0
      }
      
      if (proton.y < 0)
      {
        proton.y += 1
        proton.yvel *= -1
        proton.yac0 = 0
      }  
     
    }
    
    //Extra specialinfo genom att hålla ned spacebar
    if (keyboard.space)
    {
      text(10, 13, 10, ("Antal updateringar; " + (tidstal)), "Black")
      text(10, 26, 10, ("Antal protoner; " + z), "Black")
    }

  }

  

</script>

 

Problemet

I grunden är problemet att det finns en oönskad beteende/funktion av programmet. Den gör inte de saker som planerat.

I programmet ska protonerna ha möjlighet att knuffa undan varandra baserat på fysikens Coulombs kraft. Två laddningar som närmar varandra börjar att utföra en kraft på varandra. Kraften är lika stor på båda. Eftersom protoner har samma laddning ska de repellera varandra. Se följande illustration.

Kraften kan skrivas om för att få ut accelerationen då man tar massan till hänsyn.

F = kcq1·q2r2 ma = kcq1·q2r2 a = kcq1·q2m·r2

Jag valde att inte göra en exakt kopia av denna formel just än eftersom att jag har inte listat ut hur jag ska få dem att ändra riktning så jag nöjer mig med en förenklad formel. 

a = 1m·r a = 1r     (den angivna massan är lika med 1)

Och i exempel som ovan fungerar allt som det ska. Båda protonerna knuffar bort varandra med varsin kraft.

 

Men när man ökar antalet protoner börjar det bli konstigt. För att illustrera detta på ett begripligt vis kan jag först visa några av mina observationer och därefter en illustration av vad som sker.

Jag illustrerar med hjälp av tabeller. I fallet där vi har två protoner i programmet, dvs talet z = 2, kan både proton 1 och proton 2 påverka varandra.

Proton nummer/number Kan knuffa iväg följande
1 2
2 1

Sen senare när z blir lika med 3 börjar det bli konstigt.

Proton nummer/number Kan knuffa iväg följande
1 - (sträck betyder att den kan inte knuffa någon)
2 3
3 1, 2

 

Senare fortsätter det både i z = 4 och z = 5, varav den senare har en illustration längre ned.

Proton nr. Kan knuffa.
1 -
2 -
3 4
4 1, 2, 3
Proton nr. Kan knuffa.
1 -
2 -
3 -
4 5
5 1, 2, 3, 4

 

Detta lämnar den sista protonen till att knuffa alla, men att alla förutom den näst sista som kan knuffa tillbaks. Detta bryter mot idéen att alla ska kunna knuffa alla då de två sista protonerna får fysikalisk monopol på knuffar. Så här ska tabellen se ut ifall programmet fungerade som initialt uttänkt.

Proton nr. Kan knuffa.
1 2, 3, 4, 5
2 1, 3, 4, 5
3 1, 2, 4, 5
4 1, 2, 3, 5
5 1, 2, 3, 4

 

Alla ska kunna knuffa alla. Men nu är det inte så. Det här är illustrationen av hur det ser ut just nu.

Proton nummer fem utövar en kraft på varenda proton i sin omgivning. Endast proton nummer fyra kan göra någon motkraft.

Det här är hur den avsedda tabellen skulle se ut.

Felsökning/Debugging

Jag är osäker över ifall detta problem är för att jag har ställt upp koden i fel ordning eller ifall det fattas hela stycken av kod som ska se till att vissa delar fungerar som avsett. 

Jag har provat massvis av ändringar idag och jag har verkligen fastnat på detta problem och därmed inte kunnat fortsätta framåt.

Tabellerna över vilka som kan och inte kan knuffa är hjälpsamma i att förklara vad felet ligger någonstans. Men koden bakom lösningen till det problemet är inte uppenbart.

Jag provade att gå in på JS Bin tidigare och då försökte jag debugga genom att fråga vad proton och proton0 hade för värden i följande funktion av programmet. 

        if (proton != proton0) //HÄR är problemet, eller i alla fall vart jag anar att det kan vara. Detta uttryck fungerar inte som det ska - se utvecklad förklaring i inlägget
        {
          proton.xac = proton.xac0 + 1/distance(proton.x, proton.y, proton0.x, proton0.y);
          proton.yac = proton.yac0 + 1/distance(proton.x, proton.y, proton0.x, proton0.y);
	  console.log(//Satte in antingen proton eller proton0 här.)    
        }

Jag skrev in console.log() och satte in och testade både proton och proton0, se exemplet ovan. På det viset kunde jag se varje proton/proton0 som passerade igenom funktionen. För majoriteten av den tid som console.log(proton) så var den lika med proton nummer fem. Och när jag hade console.log(proton0) visade det främst proton nummer fyra. Detta tycker jag kan förklara varför dessa två protoner har annorlunda beteende jämfört med de andra protonerna. Men varför har jag absolut ingen aning. Min bästa gissning är att det är något fel med talen p och p0 som räknar för snabbt och kommer fram till protonerna 5 resp. 4 utan att låta de andra protonerna få utföra sina uträkningar.

Tyvär har jag inte mycket mer till förklaring. Men jag kan svara på frågor som söker specifik förklaring. Problemet är att alla protoner inte knuffar varandra. Målet är att de ska alla knuffa varandra utan att bara några få protoner knuffar endast. Jag är tacksam för all hjälp möjligt, och jag ber verkligen ursäkt över denna tråds storlek men jag har suttit fast på det här problemet tillräckligt länge att jag inte har några fler alternativ för hjälp. Tack.

(Säg också till ifall länkar inte fungerar osv.)

Svara
Close