Мой метод обработки столкновения заключается в разделении вектора скорости на две составляющие: нормальную ось и касательную ось, касательная ось перпендикулярна двум нормальным осям. Нормальная ось параллельна линии, соединяющей центры двух объектов.
Затем я преобразовываю векторную составляющую нормальной составляющей скорости в импульс.
Momentum = Velocity * Mass.
Затем я передаю импульс объекта A в B, а B в A.
Затем я нахожу соответствующую скорость для A и B на основе обменного импульса и неизменной скорости на касательной оси.
Мне кажется разумным, и это работает!
Но дело в том, что иногда возникает ошибка.
Я использую Visual Studio.
Я немного знаю об инструменте отладки, но не могу его использовать, чтобы найти ошибку.
Пожалуйста, я был бы очень признателен, если бы кто-то мог помочь.
Я уже четвертый раз пишу весь код с нуля.
Но этот же метод всегда выдает ошибку.
Так что я начинаю писать все с нуля, надеясь, что смогу как-то это исправить, организовав. Пожалуйста ... помогите.
class Vector
{
public double X = 0;
public double Y = 0;
public double Z = 0;
public Vector direction
{
get { return new Vector(0.00000001 + X / Math.Abs(X), 0.00000001 + Y / Math.Abs(Y), 0.00000001 + Z / Math.Abs(Z)); }
}
public double angle { get { return Math.Atan2(Y, Z); } }
//scholar operation
public static Vector operator + (Vector v1 , double s) {
return new Vector(v1.X + s , v1.Y + s , v1.Z +s );
}
public static Vector operator -(Vector v1, double s)
{
return new Vector(v1.X - s, v1.Y - s, v1.Z - s);
}
public static Vector operator *(Vector v, double s)
{
return new Vector(v.X * s, v.Y * s, v.Z * s);
}
//vector to vector operation
public static Vector operator +(Vector a, Vector b)
{
return new Vector(a.X + b.X, a.Y + b.Y, a.Z + b.Z);
}
public static Vector operator -(Vector a, Vector b)
{
return new Vector(a.X - b.X, a.Y - b.Y, a.Z - b.Z);
}
public static Vector operator *(Vector a, Vector b)
{
return new Vector(a.X * b.X, a.Y * b.Y, a.Z *b.Z);
}
//other operations
public static Vector operator %(Vector a, Vector b)
{
return new Vector(a.Y*b.Z - a.Z*b.Y, a.Z*b.X - a.X*b.Z , a.X*b.Y - a.Y*b.X);
}
public static double dotProduct(Vector a, Vector b)
{
Vector v = a*b;
return a.X + a.Y + a.Z;
}
public static void makeOrthonormalBasic(Vector a, Vector b, Vector c)
{
c = b % a;
if (c.squareMagnitude() != 0)
{
a = c % b;
}
}
public Vector()
{
X = 0;
Y = 0;
Z = 0;
}
public Vector(double x, double y, double z)
{
X = x;
Y = y;
Z = z;
}
public Vector (double x , double y )
{
X= x;
Y = y;
}
public void flip()
{
X *= -1;
Y *= -1;
Z *= -1;
}
public Vector fliped_vector()
{
Vector v = new Vector(X * -1, Y * -1, Z * -1);
return v;
}
public double magnitude()
{
return Math.Sqrt(X * X + Y * Y + Z * Z);
}
public double squareMagnitude() {
return X * X + Y * Y + Z * Z;
}
public Vector normalize()
{
double m = magnitude();
if (m > 0)
{
Vector v = new Vector();
v.X = this.X;
v.Y = this.Y;
v *= 1 / m;
return v;
}
return new Vector() ;
}
public void zero()
{
X = 0;
Y = 0;
}
public void set(double x, double y)
{
X = x;
Y = y;
}
public void add(double x, double y)
{
X += x;
Y += y;
}
}
class KCircle
{
double size = 30;
#region instant variables
public Ellipse shape = new Ellipse();
public Vector force = new Vector();
public Vector velocity = new Vector();
public Vector acceleration = new Vector();
public Vector position = new Vector();
#endregion
public double Vector
{
get { return Math.Sqrt(velocity.X * velocity.X + velocity.Y * velocity.Y); }
}
public double Angle
{
get { return Math.Atan2(velocity.Y, velocity.X); }
}
public double radius
{
get { return shape.Width / 2; }
}
public double mass
{
get { return Math.PI * radius * radius; }
}
public KCircle()
{
initialize();
}
public void initialize()
{
color_normal();
shape.StrokeThickness = 5;
shape.Width = shape.Height = size;
}
public void change_color()
{
shape.Fill = System.Windows.Media.Brushes.Red;
if (shape.Stroke == System.Windows.Media.Brushes.Red)
{
shape.Stroke = System.Windows.Media.Brushes.Blue;
return;
}
shape.Stroke = System.Windows.Media.Brushes.Red;
}
public void color_normal()
{
shape.Stroke = System.Windows.Media.Brushes.Black;
shape.Fill = System.Windows.Media.Brushes.White;
}
}
private void process_object_interactions(){
for (int i = 0; i < circles.Count; i++)
{
KCircle a = circles[i];
for (int z = i + 1; z < circles.Count; z++)
{
KCircle b = circles[z];
if (collide(a, b) )
{
a.change_color();
b.change_color();
Vector d = distance_between(a, b);
double angle_n = Math.Atan2(d.Y, d.X);
double angle_t = angle_n + 90;
double direction_n = 1;
double direction_t = 1;
if (angle_n < 0)
{
angle_n += 360;
}
if (angle_n > 180)
{
direction_t = -1;
}
if (angle_n > 90 && angle_n < 270)
{
angle_t = angle_n - 90;
angle_n += 180;
direction_n = -1;
}
if (angle_n > 360)
{
angle_n -= 360;
}
KCircle[] c = new KCircle[2];
c[0] = a;
c[1] = b;
double[] direction_n_array = new double[2];
direction_n_array[0] = direction_n;
direction_n_array[1] = direction_n * -1;
double[] direction_t_array = new double[2];
direction_t_array[0] = direction_t;
direction_t_array[1] = direction_t * -1;
double[] velocity_t = new double[2];
double[] velocity_n = new double[2];
for (int v = 0; v < 2; v++)
{
double angle = Math.Abs(c[i].velocity.angle - angle_n);
velocity_n[v] =(direction_n_array[v]) * (c[v].velocity.magnitude() * Math.Cos(angle));
velocity_t[v] = (direction_t_array[v]) *(c[v].velocity.magnitude() * Math.Sin(angle));
}
Vector[] new_vector_n = new Vector[2];
Vector[] momentum = new Vector[2];
for (int v = 0; v < 2; v++)
{
new_vector_n[v] = new Vector(velocity_n[v] * Math.Cos(angle_n), (velocity_n[v] * Math.Sin(angle_n)));
momentum[v] = new_vector_n[v];
momentum[v] *= c[v].mass;
}
/**
velocity_n_new[0] = normal_velocity_exchange(velocity_n[0], velocity_n[1], c[0].mass, c[1].mass);
velocity_n_new[1] = normal_velocity_exchange(velocity_n[1], velocity_n[0], c[1].mass, c[0].mass);
* */
for (int v = 0; v < 2; v++)
{
c[v].velocity.X = velocity_t[v] * Math.Cos( angle_t);
c[v].velocity.Y = -1* ((velocity_t[v] )* Math.Sin(angle_t)) ;
}
c[0].velocity += momentum[1] * (1 / c[0].mass);
c[1].velocity += momentum[0] * (1 / c[1].mass);
}
}
}
}