簡體   English   中英

剛體碰撞相對速度計算

[英]Rigid Body Collision Relative Velocity Calculation

這是我的代碼:

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

aelas是一個double,設置為1D(稍后我可以更改為函數)nv是單位法線向量

我的問題是,只有當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();
}
}

為剛體物理,IF FV將被加入這個現有的速度,並且該形狀是一個無限質量邊界此代碼行是完全正確的。 如果您的其他代碼嘗試將fv用作“最終速度”,則其計算中不應包含常數1(無論如何,斜向碰撞都是錯誤的)。

為了擴展到有限質量對的碰撞,一維常量變成有符號的加權函數,我將留給讀者練習。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM