private void AddObject(float centerX, float centerY, float angle, float speed, float radius, float mass, int r, int g, int b) { //check validity of parameters if (radius <= 0 || radius > MAX_RADIUS) { radius = GetRandValue(5, MAX_RADIUS); } if (centerX < radius || centerX > this.ClientSize.Width - radius - menu.Width) { centerX = GetRandValue((int)radius * 2 + 1, (int)(this.ClientSize.Width - radius - menu.Width)); } if (centerY < radius || centerY > this.ClientSize.Height - radius) { centerY = GetRandValue((int)radius * 2 + 1, (int)(this.ClientSize.Height - radius)); } if (angle < 0 || angle >= 360) { angle = GetRandValue(0, 360); } if (speed < 0 || speed > MAX_SPEED)// { speed = GetRandValue(0, MAX_SPEED); } if (mass < 0) //no upper bound { mass = GetRandValue(0, 10); } if (r < 0 || r > 255) { r = random.Next(0, 255); } if (g < 0 || g > 255) { g = random.Next(0, 255); } if (b < 0 || b > 255) { b = random.Next(0, 255); } //if the new object intersects an existing object, find it new coordinates for (int i = 0; DoesOverlap(centerX, centerY, radius); ++i) { centerX = GetRandValue((int)radius * 2 + 1, (int)(this.ClientSize.Width - radius - menu.Width)); centerY = GetRandValue((int)radius * 2 + 1, (int)(this.ClientSize.Height - radius)); if (i > 10) { radius = ReduceRadius(radius); } } PhysicalObject po = new PhysicalObject(centerX: centerX, centerY: centerY, angle: angle, speed: speed, radius: radius, mass: mass, color: Tuple.Create(r, g, b)); objects.Add(po); var peh = new PaintEventHandler((sender, e) => PaintObject(sender, e, po)); this.Paint += peh; paintedObjects.Add(peh); Invalidate(); }
public void CalculateCollision(PhysicalObject po1, PhysicalObject po2) { m1 = po1.Mass; m2 = po2.Mass; v1 = po1.Speed; v2 = po2.Speed; alpha = po1.Angle; //in deg beta = po2.Angle; //in deg //Console.WriteLine("\nAlpha: " + alpha); //Console.WriteLine("Beta: " + beta); inclineAngle = GetInclineAngle(po1.CenterX, po2.CenterX, po1.CenterY, po2.CenterY); //Console.WriteLine("Incline: " + inclineAngle); ShiftAngles(); //Console.WriteLine("Alpha after shift: " + alpha); //Console.WriteLine("Beta after shift: " + beta); po1.SetAxisSpeeds(alpha, v1); po2.SetAxisSpeeds(beta, v2); //Console.WriteLine("InitSpeed1: " + v1); //Console.WriteLine("InitSpeed2: " + v2); //Momentum must be calculated after angle shift CalculateMomentum(); //Console.WriteLine("Momentum: " + momentum); CalculateEnergy(); //Console.WriteLine("Energy: " + energy); CalculateU2(); //Console.WriteLine("u2: " + u2); FindU1(); //Console.WriteLine("u1: " + u1); //find new speeds and calculate new angles newSpeed1 = CalculateNewSpeed(u1, alpha, v1); //Console.WriteLine("New Speed 1: " + newSpeed1); newSpeed2 = CalculateNewSpeed(u2, beta, v2); //Console.WriteLine("New Speed 2: " + newSpeed2); newAlpha = CalculateNewAngle(newSpeed1, u1, po1.SpeedY); //Console.WriteLine("New Alpha: " + newAlpha); newBeta = CalculateNewAngle(newSpeed2, u2, po2.SpeedY); //Console.WriteLine("New Beta: " + newBeta); RestoreAngles(); //Console.WriteLine("New Alpha after restore: " + newAlpha); //Console.WriteLine("New Beta after restore: " + newBeta); po1.SetAxisSpeeds(newAlpha, Math.Abs(newSpeed1)); //spped should be positive po2.SetAxisSpeeds(newBeta, Math.Abs(newSpeed2)); //speed should be positive }
//private void AddVector() //{ //} private float CalculateGravitationalForce(PhysicalObject po1, PhysicalObject po2) { //if the object is the same the force is 0 if (DistanceSq(po1.CenterX, po1.CenterY, po2.CenterX, po2.CenterY) == 0) { return(0); } else { return(Math.Abs(gravity_const) * (po1.Mass * po2.Mass) / DistanceSq(po1.CenterX, po1.CenterY, po2.CenterX, po2.CenterY)); } }
public void ApplyGravityOn(PhysicalObject po) { for (int i = 0; i < list.Count; ++i) { //Console.WriteLine("grav force " + CalculateGravitationalForce(po, list[i])); //Console.WriteLine("grav force angle " + CalculateForceAngle(po, list[i])); AddToVector(CalculateGravitationalForce(po, list[i]) / po.Mass, CalculateForceAngle(po, list[i])); } //Console.WriteLine("force size " + vector.Item1); //Console.WriteLine("force angle " + vector.Item2); AddToVector(po.Speed, po.Angle); po.SetAxisSpeeds(vector.Item2, vector.Item1); //Console.WriteLine("New Speed " + vector.Item1); //Console.WriteLine("New Angle " + vector.Item2); vector = new Tuple <float, float>(0, 0);//nullify vector }
private void PaintObject(object sender, PaintEventArgs e, PhysicalObject po) { graphics = e.Graphics; RectangleF rect = new RectangleF(po.CenterX - po.Radius, po.CenterY - po.Radius, po.Radius * 2, po.Radius * 2); GraphicsPath path = new GraphicsPath(); path.AddEllipse(rect); PathGradientBrush pthGrBrush = new PathGradientBrush(path); //center color should be brghter; to make edges darker - lower values proportionally pthGrBrush.CenterColor = Color.FromArgb(255, po.Color.Item1, po.Color.Item2, po.Color.Item3); Color[] colors = { Color.FromArgb(255, po.Color.Item1 / 10 * 8, po.Color.Item2 / 10 * 8, po.Color.Item3 / 10 * 8) }; pthGrBrush.SurroundColors = colors; graphics.FillEllipse(pthGrBrush, rect); }
private void MoveObject(PhysicalObject po) { float newBall_x = po.CenterX + po.SpeedX; float newBall_y = po.CenterY + po.SpeedY; if (newBall_x < po.Radius || newBall_x > this.ClientSize.Width - po.Radius - menu.Width) { BounceOffVerticalWall(po); } if (newBall_y < po.Radius || newBall_y > this.ClientSize.Height - po.Radius) { BounceOffHorizontalWall(po); } po.CenterX += po.SpeedX; po.CenterY += po.SpeedY; po.CenterX += po.SpeedX; po.CenterY += po.SpeedY; Invalidate(); }
//calculates the force vector's angle private float CalculateForceAngle(PhysicalObject main, PhysicalObject second) { float dx = main.CenterX - second.CenterX; float dy = main.CenterY - second.CenterY; if (dx == 0 && dy == 0)//if same object return 0 { return(0); } float angle;// in rad //if dy < 0 -> 180 < a < 360 //if dy > 0 -> 0 < a < 180 angle = (float)Math.Atan(-(dy / dx)); angle = angle * (180 / (float)Math.PI); if (angle < 0) { angle += 180; } if (dy < 0) { angle += 180; } if (dy == 0 && dx > 0) { angle += 180; } if (gravity_const < 0) { angle += 180; angle %= 360; } return(angle); }
private void BounceOffVerticalWall(PhysicalObject po) { po.SetAxisSpeeds((540 - po.Angle) % 360, po.Speed); }
private void BounceOffHorizontalWall(PhysicalObject po) { po.SetAxisSpeeds(360 - po.Angle, po.Speed); }