/// <summary> /// Zjistí, zda objekt koliduje s jiným - daným objektem /// </summary> /// <param name="ObjectA">Účastník kolize</param> /// <param name="ObjectB">Účastník kolize</param> /// <returns>Hlášení o kolizi nebo null</returns> public static CollisionReport ObjectsCollide(SimObject ObjectA,SimObject ObjectB) { PointF[] geomA = ObjectA.Model.BoundingBox,geomB = ObjectB.Model.BoundingBox; Vector mtd = null; int Count = geomA.Length + geomB.Length; for (int i = 0, j; i < Count; i++) { Vector Axis = null; if (i < geomA.Length) { j = (i == geomA.Length - 1) ? 0 : i + 1; Vector v1 = (Vector)geomA[i]; Vector v2 = (Vector)geomA[j]; Axis = (v1 - v2).Perp(); } else { j = (i == Count - 1) ? geomA.Length : i + 1; Vector v1 = (Vector)geomB[i - geomA.Length]; Vector v2 = (Vector)geomB[j - geomA.Length]; Axis = (v1 - v2).Perp(); } if (SeparatedByAxis(Axis,ObjectA.Model, ObjectB.Model, ref mtd)) return null; } return new CollisionReport(ObjectA, ObjectB, mtd); }
/// <summary> /// Výchozí konstruktor /// </summary> /// <param name="ObjA">První účastník kolize</param> /// <param name="ObjB">Druhý účastník kolize</param> /// <param name="MinimumTranslation">Vektor minimálního posunutí</param> public CollisionReport(SimObject ObjA, SimObject ObjB,Vector MinimumTranslation) { A = ObjA; B = ObjB; MTD = MinimumTranslation; N = Vector.Unit(MTD); Prepare(); NAP = ((Vector)Pairs[0].A - A.COG).Perp(); NBP = ((Vector)Pairs[0].B - B.COG).Perp(); RelativeVelocity = (A.LinearVelocity + Vector.Cross(NAP.Perp(), A.AngularVelocity)) - (B.LinearVelocity + Vector.Cross(NBP.Perp(), B.AngularVelocity)); }
private void newObj_Insert_Click(object sender, EventArgs e) { if (newObj_Mass.Text.Length == 0 && !newObj_Static.Checked) { MessageBox.Show("Zadejte hmotnost tělesa","Chyba",MessageBoxButtons.OK,MessageBoxIcon.Exclamation); return; } if (newObj_Geometry.SelectedIndex < 0) { MessageBox.Show("Vyberte geometrii pro těleso", "Chyba", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } if (newObj_Material.SelectedIndex < 0) { MessageBox.Show("Vyberte materiál pro těleso", "Chyba", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } GraphicObject Placing = GraphicObject.LoadFromFile(@"objects\" + newObj_Geometry.SelectedItem.ToString() + ".xml"); if (newObj_AutoName.Checked) Placing.Name = String.Format("object_#{0}", MyOwner.MyWorld.CountObjects); else Placing.Name = newObj_Name.Text; Material MyMat = Material.Concrete; switch (newObj_Material.SelectedIndex) { case 1: MyMat = Material.Wood; break; case 2: MyMat = Material.Concrete; break; case 3: MyMat = Material.Steel; break; case 4: MyMat = Material.Rubber; break; default: MyMat = Material.Concrete; break; } double MyMass = 0; if (!Double.TryParse(newObj_Mass.Text, out MyMass)) MyMass = 1000; SimObject MyNewObject = new SimObject(Placing, MyMass/1000, MyMat); MyNewObject.Enabled = newObj_Enabled.Checked; MyNewObject.Static = newObj_Static.Checked; MyOwner.Focus(); MyOwner.AddObject(MyNewObject); tab_Toolbox.Enabled = false; }
/// <summary> /// Spočítá všechny typy energií pro dané těleso /// </summary> /// <param name="Object">Těleso</param> /// <param name="Units">Jednotky</param> /// <returns>Energie</returns> public ObjectEnergy GetObjectEnergy(SimObject Object,ConversionType Units = ConversionType.MetersToPixels) { if (Object == null) throw new ArgumentNullException(); ObjectEnergy Ret = new ObjectEnergy(); if (Units == ConversionType.MetersToPixels) { Ret.Kinetic = 0.5 * Object.Mass * Vector.Pow(Object.LinearVelocity, 2); Ret.Potential = Object.Mass * Vector.PointDistance(new Vector(Object.COG[0], Level[1], 0), Object.COG) * Gravity.Magnitude; } else { Ret.Kinetic = 0.5 * Object.Mass * Vector.Pow(Convert(Object.LinearVelocity,ConversionType.PixelsToMeters), 2); Ret.Potential = Object.Mass * Convert(Vector.PointDistance(new Vector(Object.COG[0], Level[1], 0), Object.COG),ConversionType.PixelsToMeters) * Convert(Gravity,ConversionType.PixelsToMeters).Magnitude; } Ret.Rotational = 0.5 * Object.Mass * Object.MomentOfInertia * Vector.Pow(Object.AngularVelocity, 2); return Ret; }
/// <summary> /// Přidá těleso do světa /// </summary> /// <param name="O">Těleso</param> /// <returns>Index tělesa</returns> public int AddObject(SimObject O) { lock (SimLock) { O.InitialEnergy = O.Mass * Gravity.Magnitude * Vector.PointDistance(new Vector(O.COG[0], Level[1], 0), O.COG); Objs.Add(O); } return Objs.Count - 1; }