public void drag(double px, double py, ball b) { double x = py; double y = px; m_x = x - (m_length / 2) * (x - b.m_x) / Math.Sqrt((y - b.m_y) * (y - b.m_y) + (x - b.m_x) * (x - b.m_x)); m_y = y - (m_length / 2) * (y - b.m_y) / Math.Sqrt((y - b.m_y) * (y - b.m_y) + (x - b.m_x) * (x - b.m_x)); double geg = x - b.m_x; double ank = y - b.m_y; double quot = ank / Math.Sqrt(ank * ank + geg * geg); if (geg < 0) { m_angle = 2 * Math.PI - Math.Acos(quot); } else { m_angle = Math.Acos(quot); } m_line.X1 = m_y + (m_length / 2) * Math.Cos(m_angle); m_line.Y1 = m_x + (m_length / 2) * Math.Sin(m_angle); m_line.X2 = m_y - (m_length / 2) * Math.Cos(m_angle); m_line.Y2 = m_x - (m_length / 2) * Math.Sin(m_angle); Canvas.SetLeft(m_knob, m_y + (m_length / 2) * Math.Cos(m_angle) - 5); Canvas.SetTop(m_knob, m_x + (m_length / 2) * Math.Sin(m_angle) - 5); }
public bool collision(ball ball, uint dt) { bool hit = false; if (distance(ball) <= 2 * m_radius) { hit = true; double tk; // Vorbereitung der Positionskorrektur double a = ((m_y - m_yold) - (ball.m_y - ball.m_yold)) * ((m_y - m_yold) - (ball.m_y - ball.m_yold)) + ((m_x - m_xold) - (ball.m_x - ball.m_xold)) * ((m_x - m_xold) - (ball.m_x - ball.m_xold)); double b = (2 * (m_yold - ball.m_yold) * ((m_y - m_yold) - (ball.m_y - ball.m_yold))) + (2 * (m_xold - ball.m_xold) * ((m_x - m_xold) - (ball.m_x - ball.m_xold))); double c = ((m_xold - ball.m_xold) * (m_xold - ball.m_xold)) + ((m_yold - ball.m_yold) * (m_yold - ball.m_yold)) - (4 * (m_radius * m_radius)); double p = b / a; double q = c / a; double tk1 = -(p / 2) + Math.Sqrt(((p / 2) * (p / 2)) - q); double tk2 = -(p / 2) - Math.Sqrt(((p / 2) * (p / 2)) - q); if (tk1 >= 0 && tk1 <= 1) { tk = tk1; } else { tk = tk2; } // Positionskorrektur, so dass sich die Kugeln gerade berühren double x1 = m_xold + (m_x - m_xold) * tk; double x2 = ball.m_xold + (ball.m_x - ball.m_xold) * tk; double y1 = m_yold + (m_y - m_yold) * tk; double y2 = ball.m_yold + (ball.m_y - ball.m_yold) * tk; // Winkelfunktionen für die Koordinatentransformation (muss mit den korrigierten // Werten berechnet werden) double cos_a = (x2 - x1) / (2 * m_radius); double sin_a = (y2 - y1) / (2 * m_radius); // Koordinatentransformation der Geschwindigkeitsvektoren double am_vx = cos_a * m_vx + sin_a * m_vy; double am_vy = -sin_a * m_vx + cos_a * m_vy; double bm_vx = cos_a * ball.m_vx + sin_a * ball.m_vy; double bm_vy = -sin_a * ball.m_vx + cos_a * ball.m_vy; // Zentralkomponenten des Impulses austauschen double save = bm_vx; bm_vx = am_vx; am_vx = save; // Rücktransformation m_vx = cos_a * am_vx - sin_a * am_vy; m_vy = sin_a * am_vx + cos_a * am_vy; ball.m_vx = cos_a * bm_vx - sin_a * bm_vy; ball.m_vy = sin_a * bm_vx + cos_a * bm_vy; // Endgültige Positionskorrektur mit rücktransformiertem Vektor m_x = x1 + m_vx * dt * (1 - tk) / 1000; m_y = y1 + m_vy * dt * (1 - tk) / 1000; ball.m_x = x2 + ball.m_vx * dt * (1 - tk) / 1000; ball.m_y = y2 + ball.m_vy * dt * (1 - tk) / 1000; setLTWH(); } return hit; }
public double distance(ball b) { return Math.Sqrt((m_x - b.m_x) * (m_x - b.m_x) + (m_y - b.m_y) * (m_y - b.m_y)); }
public void shoot(ball b) { double tip_y = m_y - (m_length / 2) * Math.Cos(m_angle); double tip_x = m_x - (m_length / 2) * Math.Sin(m_angle); double dist = Math.Sqrt((b.m_x - tip_x) * (b.m_x - tip_x) + (b.m_y - tip_y) * (b.m_y - tip_y)); if (dist > b.m_radius && dist < 2.0 * b.m_radius) { b.m_vx = -m_impulse * Math.Sin(m_angle); b.m_vy = -m_impulse * Math.Cos(m_angle); } }
public billard() { m_dlg = new startdlg(); if ((bool)m_dlg.ShowDialog()) { m_name1 = m_dlg.m_name1; m_name2 = m_dlg.m_name2; } else { Close(); } InitializeComponent(); spieler1.FontFamily = new FontFamily("Courier New"); spieler1.FontSize = 20F; spieler1.FontWeight = FontWeights.Bold; spieler1.Foreground = Brushes.Green; spieler2.FontFamily = new FontFamily("Courier New"); spieler2.FontSize = 20F; spieler2.FontWeight = FontWeights.Regular; spieler2.Foreground = Brushes.Gray; zeit.FontFamily = new FontFamily("Courier New"); zeit.FontSize = 20F; zeit.FontWeight = FontWeights.Bold; zeit.Foreground = Brushes.DarkCyan; Canvas.SetLeft(m_frame, 135); Canvas.SetTop(m_frame, 195); LinearGradientBrush brush = new LinearGradientBrush(); brush.GradientStops.Add(new GradientStop(Colors.Brown, 0.0)); brush.GradientStops.Add(new GradientStop(Colors.Chocolate, 1.0)); m_frame.Fill = brush; m_frame.Width = 630; // SetBottom, SetRight reicht nicht ==> kein Rechteck zu sehen m_frame.Height = 330; m_frame.RadiusX = 15; m_frame.RadiusY = 15; m_canvas.Children.Add(m_frame); Canvas.SetLeft(m_table, 150); Canvas.SetTop(m_table, 210); m_table.Fill = System.Windows.Media.Brushes.Green; m_table.Width = 600; m_table.Height = 300; m_canvas.Children.Add(m_table); m_balls = new ball[3]; m_balls[0] = new ball(350, 800, m_dlg.m_radius, 0.0005, System.Drawing.Color.White); m_balls[1] = new ball(280, 220, m_dlg.m_radius, 0.0005, System.Drawing.Color.Yellow); m_balls[2] = new ball(420, 220, m_dlg.m_radius, 0.0005, System.Drawing.Color.Red); foreach (ball ball in m_balls) { m_canvas.Children.Add(ball.m_theball); // Damit wird der Ball gerendert } m_cue = new cue(); m_canvas.Children.Add(m_cue.m_line); m_canvas.Children.Add(m_cue.m_laser); m_canvas.Children.Add(m_cue.m_knob); radius.Value = m_dlg.m_radius; impulse.Value = 1000; }