2014-01-10 3 views
0

Это мой код:твердого тела Столкновение Относительная скорость Расчет

Vec2 fv = nv.scale(-((1D + aelas) * getLinearVelocity().sub(shape.getLinearVelocity()).dot(nv))); 

aelas является двойным, установите 1D (в дальнейшем я могу изменить к функции) пу единичный нормальный вектор

Моя проблема заключается в том, что столкновение корректно реагирует с идеальной эластичностью, когда aelas равно 0, но когда оно равно 1, оно относится к нему так, как будто эластичность> 2D (поэтому больше энергии гаснет, а затем приходит).

Я считаю, что моя система относительной скорости неверна, что приводит к ее неправильной реакции.

Я полностью отладил свой код и довольно уверен, что это моя математика. Кто-нибудь хочет поделиться некоторым пониманием?

vec2 Класс:

package JavaProphet.Profis.Geometry; 

/** 
* Created by JavaProphet on 12/8/13 at 12:28 PM. 
*/ 
public class Vec2 { 
private final double x; 
private final double y; 
public static final Vec2 ZERO_VEC = new Vec2(0D, 0D); 

/** 
* Empty Vector. 
*/ 
public Vec2() { 
    x = 0D; 
    y = 0D; 
} 

public String toString() { 
    return "<" + getX() + ", " + getY() + ">"; 
} 

/** 
* Uses basic trigonometry to create a Vec2 from a radian. 
* 
* @param rad The radian. 
*/ 
public Vec2(double rad) { 
    x = Math.sin(rad); 
    y = Math.cos(rad); 
} 

/** 
* Assigns a vector it's value. 
*/ 
public Vec2(double x, double y) { 
    this.x = x; 
    this.y = y; 
} 

/** 
* Assigns a vector it's value from a double array of length 2. 
*/ 
public Vec2(double v[]) { 
    this.x = v[0]; 
    this.y = v[1]; 
} 

/** 
* Assigns a vector it's value from subtraction of position. 
* 
* @param x x1 
* @param x2 x2 
* @param y y1 
* @param y2 y 
*/ 
public Vec2(double x, double y, double x2, double y2) { 
    this.x = x2 - x; 
    this.y = y2 - y; 
} 

/** 
* @return The x value from the vector. 
*/ 
public double getX() { 
    return x; 
} 

/** 
* @return The y value from the vector. 
*/ 
public double getY() { 
    return y; 
} 

/** 
* Adds two vectors. 
*/ 
public Vec2 add(Vec2 vec) { 
    return new Vec2(getX() + vec.getX(), getY() + vec.getY()); 
} 

/** 
* Subtracts two vectors. 
*/ 
public Vec2 sub(Vec2 vec) { 
    return new Vec2(getX() - vec.getX(), getY() - vec.getY()); 
} 

/** 
* Performs a dot product on two vectors. 
*/ 
public double dot(Vec2 vec) { 
    return getX() * vec.getX() + getY() * vec.getY(); 
} 

/** 
* Scales magnitude of a vector by a scalar. 
* 
* @param sc The scalar. 
*/ 
public Vec2 scale(double sc) { 
    return new Vec2(getX() * sc, getY() * sc); 
} 

/** 
* Scales magnitude of a vector by two scalars. 
* 
* @param x The x scalar. 
* @param y The y scalar. 
*/ 
public Vec2 scale(double x, double y) { 
    return new Vec2(getX() * x, getY() * y); 
} 

public boolean equals(Vec2 vec) { 
    return vec.getX() == getX() && vec.getY() == getY(); 
} 

public double relativeCosine(Vec2 vec) { 
    double d = dot(vec); 
    double rc = d/(getMagnitude() * vec.getMagnitude()); 
    return rc; 
} 

public double relativeRadian(Vec2 vec) { 
    return Math.acos(relativeCosine(vec)); 
} 

public double getRot() { 
    return Math.atan2(getY(), getX()); 
} 

/** 
* Rotates the vector around the origin. 
* 
* @param rad A radian to rotate by. 
* @return The result. 
*/ 
public Vec2 rot(double rad) { 
    double sin = Math.sin(rad); 
    double cos = Math.cos(rad); 
    double t1 = ((cos * getX()) - (sin * getY())); 
    double t2 = ((sin * getX()) + (cos * getY())); 
    return new Vec2(t1, t2); 
} 

/** 
* Retrieves the slope for this vector. 
* 
* @param vec A vector in which is paired to make a line segment. 
* @return A slope. 
*/ 
public double slope(Vec2 vec) { 
    return (vec.getX() - getX())/(vec.getY() - getY()); 
} 

/** 
* Scales magnitude of a vector to a tracable amount. (1/x, 1/y) 
*/ 
public Vec2 tscale() { 
    return new Vec2(1D/getX(), 1D/getY()); 
} 

/** 
* Inverts a vector(-x, -y). 
*/ 
public Vec2 invert() { 
    return new Vec2(-getX(), -getY()); 
} 

private double mag = 0D; // magnitude cannot be 0, so if zero, calc mag. 

/** 
* Return the length, or magnitude of a vector, uses sqrt. 
*/ 
public double getMagnitude() { 
    if(mag == 0D && (getX() != 0D || getY() != 0D)) { 
     mag = Math.sqrt(Math.pow(getX(), 2) + Math.pow(getY(), 2)); 
    } 
    return mag; 
} 

/** 
* Converts a vector to a unit vector (x/length, y/length), uses sqrt. 
*/ 
public Vec2 uscale() { 
    double length = getMagnitude(); 
    return new Vec2(getX()/length, getY()/length); 
} 

/** 
* Converts a vector to a unit vector (x/length, y/length), uses sqrt. 
*/ 
public Vec2 hat() { 
    return uscale(); 
} 
} 
+1

Разделите вычисления на несколько строк, распечатайте каждую строку и проверьте вывод – vandale

+0

Да (как говорит вандейл), моя физика стала ржавой, но не является реальной проблемой, что getLinearVelocity(). Sub (shape.getLinearVelocity()). dot (nv))) больше 1, и этого не должно быть. Можете ли вы опубликовать getLinearVelocity? –

+0

@JimW Вот вывод я сделал:.. getLinearVelocity() суб (shape.getLinearVelocity()) точка (NV)) = 2,0 getLinearVelocity (.) К югу (shape.getLinearVelocity()) = <0.0, 2.0> getLinearVelocity () = <0.0, 1.0> shape.getLinearVelocity() = <0.0, -1.0> пу = <0.0, 1.0> бс = <-0.0, -4.0> – user2507230

ответ

0

Для физики твердого тела, эта строка кода является вполне корректным IF бс будет добавлена ​​ к существующей скорости это и форма является бесконечной границей массы. Если ваш другой код пытается использовать fv как «конечную скорость», он не должен иметь константу 1 в ее вычислении (и в любом случае это просто неправильно в косых столкновениях).

Для продолжения к столкновениям с конечной массой пара 1D-константа превращается в подписанную весовую функцию, которую я оставлю в качестве упражнения для читателя.

Смежные вопросы