/// <summary> /// Bewegungsrichtungsänderung durch Beschleunigung zum Objekt /// </summary> /// <param name="o">Bezugsobjekt</param> /// <returns>Richtungsvektor</returns> public Point3 _v(o2Object o) { Point3 _a = new Point3(); _a = a(o); return(Direction = Direction + (_a * PlanetAdvanced2.dt)); }
public void RemoveObj(o2Object that) { Objects.Remove(that); Objects0.Remove(that); Objects1.Remove(that); Objects2.Remove(that); Objects3.Remove(that); }
/// <summary> /// Constructor /// </summary> /// <param name="Pos">Position</param> /// <param name="Dir">Richtung</param> /// <param name="mass">Masse</param> /// <param name="Color">Farbarray</param> /// <param name="_Parent">Bewegung kann sich auch nur auf den Parent beziehen</param> public o2Object(Point3 Pos, Point3 Dir, float mass, float[] Color, o2Object _Parent) { Position = Pos; Direction = Dir; Mass = mass; Farbe = Color; Parent = _Parent; }
/// <summary> /// Zufällige Position bezogen auf ein Zentralobjekt /// </summary> /// <param name="_Sun">Zentralobjekt</param> /// <param name="isSun">Ist neues Objekt eine Sonne?</param> /// <param name="SunIsParent">Ist die Hauptsonne das Zentralobjekt?</param> /// <returns>beliebiger Vektor zu einer Position in der Nähe des Zentralobjektes</returns> private Point3 RndPosToSun(o2Object _Sun, bool isSun, bool SunIsParent) { Point3 result = new Point3(); result.x = _Sun.Position.x + Calc(_Sun, isSun, SunIsParent); result.y = _Sun.Position.y + Calc(_Sun, isSun, SunIsParent); result.z = _Sun.Position.z + fak() * (float)rnd.NextDouble() * 100f; return(result); }
/// <summary> /// Beschleunigung Richtung Bezugsobjekt /// </summary> /// <param name="o">Bezugsobjekt</param> /// <returns></returns> private Point3 a(o2Object o) { float distance = Point3.Distance(this.Position, o.Position); Point3 x = new Point3(); x.assign(Position - o.Position); float fak = (float)(-PlanetAdvanced2.G * o.Mass / Math.Pow(distance, 3)); return(x * fak); }
/// <summary> /// Ein Planet soll zu einer Sonne werden ab einer bestimmten Masse /// </summary> /// <param name="Planet2Convert">zu verändernder Planet</param> private void ConvertPlanet2Sun(o2Object Planet2Convert) { if ( (suncount < PlanetAdvanced2._Light.Length - 1) && (Planet2Convert.Mass > PlanetAdvanced3.initSunMass * 0.5)) { suncount++; // Sonnenzähler erhöhen. (wichtig wegen Lichtquellen); Sun = new o2Sun(Planet2Convert.Position, Planet2Convert.Direction, Planet2Convert.Mass, Planet2Convert.Farbe, PlanetAdvanced2._Light[suncount]); Objects.Add(Sun); Objects.Remove(Planet2Convert); // Convertierten Planeten löschen } }
/// <summary> /// Fügt einem Zentralobjekt untergeordnete es umkreisende Objekte hinzu /// </summary> /// <param name="cnt">Anzahl der das Zentralobjekt umkreisenden Objekte</param> private void AddDust(int cnt) { for (int i = 0; i < cnt; i++) { float Mass = 1f; int ps = rnd.Next(28, 30); Mass = (float)rnd.NextDouble() * (float)Math.Pow(10, ps) * PlanetAdvanced2.UniFak; // Größe Abhängig von Basisgröße der Planeten Point3 Pos = RndDustPosToSun(); // Position soll relativ zum Ursprung sein Point3 Dir = new Point3(); float[] Color = { (float)rnd.NextDouble(), (float)rnd.NextDouble(), (float)rnd.NextDouble() }; // Farbe ist zufällig o2Object p = new o2Object(Pos, Dir, Mass, Color, null); Objects.Add(p); } }
/// <summary> /// Hier wird die neue Position in Abhängigkeit von der Masse des Zentralkörpers bestimmt. /// </summary> /// <param name="_Sun">Zentralkörper</param> /// <param name="isSun">ist Zentralkörper eine Sonne?</param> /// <param name="SunIsParent">ist Zentralkörper die Hauptsonne?</param> /// <returns>zufällig generierten Wert abhängig von Masse und Art des Zentralkörpers</returns> private float Calc(o2Object _Sun, bool isSun, bool SunIsParent) { // return _Sun.Size() / 2 + (float)rnd.NextDouble() * fak * Sun.Mass / initSunSize * 10000; if (!isSun) { if (!SunIsParent) { return(_Sun.Size / 2 + (float)rnd.NextDouble() * fak() * _Sun.Size * 10); } else { return(_Sun.Size / 2 + (float)rnd.NextDouble() * fak() * _Sun.Size * 30); } } else { return(_Sun.Size / 2 + (float)rnd.NextDouble() * fak() * _Sun.Size * 55); } }
/// <summary> /// Fügt einem Zentralobjekt untergeordnete es umkreisende Objekte hinzu /// </summary> /// <param name="_ZentralObjekt">Dies ist das Zentralobjekt um welches die hinzugefügten kreisen sollen</param> /// <param name="cnt">Anzahl der das Zentralobjekt umkreisenden Objekte</param> private void AddPlanet(o2Object _ZentralObjekt, int cnt) { bool SunIsParent = _ZentralObjekt is o2Sun; // ist das Zentralobjekt eine Sonne? for (int i = 0; i < cnt; i++) { float Mass = 1f; if (SunIsParent) // Planet { int ps = rnd.Next(28, 30); Mass = (float)rnd.NextDouble() * (float)Math.Pow(10, ps) * PlanetAdvanced2.UniFak; // Größe Abhängig von Basisgröße der Planeten } else // Mond. { float f = rnd.Next(80, 1000); // Faktor um wie viel der Mond kleiner sein soll, als der Körper um den er kreist. Mass = _ZentralObjekt.Mass / f; // Erd-Mond ist ca. 1/81 der Erdmasse. Da er der Größte im Sonnensystem ist, nehm ich das Verhältnis als max. an. } Point3 Pos = RndPosToSun(_ZentralObjekt, false, SunIsParent); // Position soll relativ zum Zentralkörper sein float distance = Point3.Distance(_ZentralObjekt.Position, Pos); Point3 Dir = MM.MatDotPoint(RotMatrix90z(), Pos - _ZentralObjekt.Position); // Richtung 90Grad zum Sonnenwinkel Dir.Normalize(); Dir *= (float)Math.Sqrt(PlanetAdvanced2.G * _ZentralObjekt.Mass / distance); // *fak(); // 1. kosmische Geschwindigkeit (Rotation auf Kreisbahn). Dir += Dir * ((float)rnd.NextDouble() / 10f); //* fak()); // ein wenig Varianz, um es interessannt zu machen. Dir += _ZentralObjekt.Direction; // Bewegung der Bezugssonne draufrechnen, damit Sich Planet mitbewegt. float[] Color = { (float)rnd.NextDouble(), (float)rnd.NextDouble(), (float)rnd.NextDouble() }; // Farbe ist zufällig o2Object p = new o2Object(Pos, Dir, Mass, Color, null); Objects.Add(p); getList().Add(p); if (SunIsParent) { int c = rnd.Next(0, 4); AddPlanet(p, c); } } }
/// <summary> /// Hier wird die neue Position in Abhängigkeit von der Masse des Zentralkörpers bestimmt. /// </summary> /// <param name="_Sun">Zentralkörper</param> /// <param name="isSun">ist Zentralkörper eine Sonne?</param> /// <param name="SunIsParent">ist Zentralkörper die Hauptsonne?</param> /// <returns>zufällig generierten Wert abhängig von Masse und Art des Zentralkörpers</returns> private float Calc(o2Object _Sun, bool isSun, bool SunIsParent) { // return _Sun.Size() / 2 + (float)rnd.NextDouble() * fak * Sun.Mass / initSunSize * 10000; if (!isSun) { if (!SunIsParent) { return _Sun.Size / 2 + (float)rnd.NextDouble() * fak() * _Sun.Size * 10; } else { return _Sun.Size / 2 + (float)rnd.NextDouble() * fak() * _Sun.Size * 30; } } else { return _Sun.Size / 2 + (float)rnd.NextDouble() * fak() * _Sun.Size * 55; } }
/// <summary> /// Fügt einem Zentralobjekt untergeordnete es umkreisende Objekte hinzu /// </summary> /// <param name="_ZentralObjekt">Dies ist das Zentralobjekt um welches die hinzugefügten kreisen sollen</param> /// <param name="cnt">Anzahl der das Zentralobjekt umkreisenden Objekte</param> private void AddPlanet(o2Object _ZentralObjekt, int cnt) { bool SunIsParent = _ZentralObjekt is o2Sun; // ist das Zentralobjekt eine Sonne? for (int i = 0; i < cnt; i++) { float Mass = 1f; if (SunIsParent) // Planet { int ps = rnd.Next(28, 30); Mass = (float)rnd.NextDouble() * (float)Math.Pow(10, ps) * PlanetAdvanced2.UniFak; // Größe Abhängig von Basisgröße der Planeten } else // Mond. { float f = rnd.Next(80, 1000); // Faktor um wie viel der Mond kleiner sein soll, als der Körper um den er kreist. Mass = _ZentralObjekt.Mass / f; // Erd-Mond ist ca. 1/81 der Erdmasse. Da er der Größte im Sonnensystem ist, nehm ich das Verhältnis als max. an. } Point3 Pos = RndPosToSun(_ZentralObjekt, false, SunIsParent); // Position soll relativ zum Zentralkörper sein float distance = Point3.Distance(_ZentralObjekt.Position, Pos); Point3 Dir = MM.MatDotPoint(RotMatrix90z(), Pos - _ZentralObjekt.Position); // Richtung 90Grad zum Sonnenwinkel Dir.Normalize(); Dir *= (float)Math.Sqrt(PlanetAdvanced2.G * _ZentralObjekt.Mass / distance);// *fak(); // 1. kosmische Geschwindigkeit (Rotation auf Kreisbahn). Dir += Dir * ((float)rnd.NextDouble() / 10f); //* fak()); // ein wenig Varianz, um es interessannt zu machen. Dir += _ZentralObjekt.Direction; // Bewegung der Bezugssonne draufrechnen, damit Sich Planet mitbewegt. float[] Color = { (float)rnd.NextDouble(), (float)rnd.NextDouble(), (float)rnd.NextDouble() }; // Farbe ist zufällig o2Object p = new o2Object(Pos, Dir, Mass, Color,null); Objects.Add(p); if (SunIsParent) { int c = rnd.Next(0, 4); AddPlanet(p, c); } } }
/// <summary> /// Fügt einem Zentralobjekt untergeordnete es umkreisende Objekte hinzu /// </summary> /// <param name="cnt">Anzahl der das Zentralobjekt umkreisenden Objekte</param> private void AddDust(int cnt) { for (int i = 0; i < cnt; i++) { float Mass = 1f; int ps = rnd.Next(28, 30); Mass = (float)rnd.NextDouble() * (float)Math.Pow(10, ps) * PlanetAdvanced2.UniFak; // Größe Abhängig von Basisgröße der Planeten Point3 Pos = RndDustPosToSun(); // Position soll relativ zum Ursprung sein Point3 Dir = new Point3(); float[] Color = { (float)rnd.NextDouble(), (float)rnd.NextDouble(), (float)rnd.NextDouble() }; // Farbe ist zufällig o2Object p = new o2Object(Pos, Dir, Mass, Color,null); Objects.Add(p); } }
/// <summary> /// Beschleunigung Richtung Bezugsobjekt /// </summary> /// <param name="o">Bezugsobjekt</param> /// <returns></returns> private Point3 a(o2Object o) { float distance = Point3.Distance(this.Position, o.Position); Point3 x = new Point3(); x.assign(Position - o.Position); float fak = (float)(-PlanetAdvanced2.G * o.Mass / Math.Pow(distance, 3)); return x * fak; }
/// <summary> /// Bewegungsrichtungsänderung durch Beschleunigung zum Objekt /// </summary> /// <param name="o">Bezugsobjekt</param> /// <returns>Richtungsvektor</returns> public Point3 _v(o2Object o) { Point3 _a = new Point3(); _a = a(o); return Direction = Direction + (_a * PlanetAdvanced2.dt); }
/// <summary> /// Zufällige Position bezogen auf ein Zentralobjekt /// </summary> /// <param name="_Sun">Zentralobjekt</param> /// <param name="isSun">Ist neues Objekt eine Sonne?</param> /// <param name="SunIsParent">Ist die Hauptsonne das Zentralobjekt?</param> /// <returns>beliebiger Vektor zu einer Position in der Nähe des Zentralobjektes</returns> private Point3 RndPosToSun(o2Object _Sun, bool isSun , bool SunIsParent) { Point3 result = new Point3(); result.x = _Sun.Position.x + Calc(_Sun, isSun, SunIsParent); result.y = _Sun.Position.y + Calc(_Sun, isSun, SunIsParent); result.z = _Sun.Position.z + fak() * (float)rnd.NextDouble() * 100f; return result; }
/// <summary> /// eine Simulationsperiode /// </summary> private void ThreadTick() { float distance; float ri; float rj; o2Object oi; o2Object oj; try { #region Bewegung foreach (o2Object o in Objects) { o.MoveObject(Objects); if (showTrace) { o.Trace(); } } #endregion } catch { } try // Wegen Threading kommt es gern zu Fehlern beim Entfernen von Objekten. Das wird hier abgefangen. { // ist unsauber und langsamer, ich weiß. #region Kollision // Kollisionsabfrage Schwereres Objekt bekommt Masse von leichterem Objekt // und der Impuls des kleineren wird auf den größeren gerechnet. // Sonne wird nicht zerstört, da sie Lichtquelle ist. for (int i = 0; i < Objects.Count - 1; i++) { for (int j = i + 1; j < Objects.Count; j++) { oi = Objects[i]; oj = Objects[j]; distance = Point3.Distance(oi.Position, oj.Position); Point3 impulse = new Point3(); ri = oi.Size; rj = oj.Size; if (ri + rj > distance) // Objekte kollidieren ( Summe der Radien > Abstand ) { impulse = (oi.Direction * oi.Mass) + (oj.Direction * oj.Mass); if (Objects[i] == Sun) // erstes Objekt ist die HauptSonne - Hauptsonne soll bleiben. { Sun.Mass += oj.Mass; Sun.Direction = impulse / Sun.Mass; Objects.Remove(oj); ConvertPlanet2Sun(oi); break; } else { if (Objects[j] == Sun) // zweites Objekt ist die Hauptsonne - Hauptsonne soll bleiben { Sun.Mass += oi.Mass; Sun.Direction = impulse / Sun.Mass; Objects.Remove(oi); ConvertPlanet2Sun(oj); break; } else // Kein Objekt ist die Hauptsonne. { if (oi.Mass > oj.Mass) { oi.Mass += oj.Mass; oi.Direction = impulse / oi.Mass; Objects.Remove(oj); ConvertPlanet2Sun(oi); break; } else { oj.Mass += oi.Mass; oj.Direction = impulse / oj.Mass; Objects.Remove(oi); ConvertPlanet2Sun(oj); break; } } } } } } #endregion } catch { } try // Wegen Threading kommt es gern zu Fehlern beim Entfernen von Objekten. Das wird hier abgefangen. { // ist unsauber und langsamer, ich weiß. #region zu weit vom Ursprung entfernte Objekte entfernen for (int i = Objects.Count - 1; i >= 0; i--) { o2Object o = Objects[i]; distance = Point3.Distance(new Point3(), o.Position); if (distance > 1000000) { if (o == Sun) { Sun.Direction = new Point3(); Sun.Position = new Point3(); } else { Objects.Remove(o); } } } #endregion } catch (Exception) { } if (Sun != null && centered) { resetSun(); } }