gpt4 book ai didi

java - 二维绳索模拟

转载 作者:搜寻专家 更新时间:2023-11-01 03:36:01 28 4
gpt4 key购买 nike

我正在尝试制作 2D 绳索模拟,但它的行为很奇怪,并且在我运行它时会跳来跳去。它也永远不会安定下来,就好像它永远不会失去动能,即使我有一个摩擦系数。 simulation

public class Rope {

private static final double FRICTION_COEF = 0.9;

public double maxStretchLength;

private Vec2D gravity = new Vec2D();
private final List<Node> nodes = new ArrayList<>();

public Rope(final int nodes, final int length, final Vec2D startingLocation) {
for (int i = 0; i < nodes; i++) {
final Node node = new Node();
node.location = startingLocation;
node.velocity = new Vec2D();
if (i != 0) {
node.above = getNodes().get(i - 1);
getNodes().get(i - 1).below = node;
}
getNodes().add(node);
}
maxStretchLength = length / nodes;
}

public void draw(final Graphics g) {
final int radius = 5;
for (final Node n : getNodes()) {
g.setColor(Color.RED);
g.fillOval((int) n.location.x - radius, (int) n.location.y - radius, radius * 2, radius * 2);
if (n.above != null) {
g.setColor(Color.BLUE);
g.drawLine((int) n.location.x, (int) n.location.y, (int) n.above.location.x, (int) n.above.location.y);
}
}
}

public void update() {
for (final Node n : getNodes()) {
Vec2D force = gravity;

if (!n.isFixed()) {
force = force.plus(n.above.location.minus(n.location).multiply(FRICTION_COEF));
// equal and opposite force
if (!n.above.isFixed()) {
n.above.velocity = n.above.velocity.plus(force.multiply(-1));
}
}

n.velocity = n.velocity.plus(force);
if (n.isFixed()) {
n.velocity = new Vec2D(0, 0);
}
}
for (final Node n : getNodes()) {
n.location = n.location.plus(n.velocity);
}
}

public void applyGravity(final Vec2D v) {
gravity = gravity.plus(v);
}

public List<Node> getNodes() {
return nodes;
}

public static class Node {
public Vec2D location;
public Vec2D velocity;
public Node above;
public Node below;

public double distance(final Node other) {
return other.location.distance(location);
}

public boolean isFixed() {
return above == null;
}
}
}

public class Vec2D extends Point2D.Double {

/*
* (non-Javadoc)
*
* @see java.awt.geom.Point2D.Double#Point2D.Double()
*/
public Vec2D() {
super();
}

/*
* (non-Javadoc)
*
* @see java.awt.geom.Point2D.Double#Point2D.Double()
*/
public Vec2D(final double x, final double y) {
super(x, y);
}

/**
* Copy constructor
*/
public Vec2D(final Vec2D v) {
x = v.x;
y = v.y;
}

/**
* @return the radius (length, modulus) of the vector in polar coordinates
*/
public double getR() {
return Math.sqrt(x * x + y * y);
}

/**
* @return the angle (argument) of the vector in polar coordinates in the
* range [-pi/2, pi/2]
*/
public double getTheta() {
return Math.atan2(y, x);
}

/*
* (non-Javadoc)
*
* @see java.awt.geom.Point2D.Double#setLocation(double, double)
*/
public void set(final double x, final double y) {
super.setLocation(x, y);
}

/**
* Sets the vector given polar arguments.
*
* @param r
* The new radius
* @param t
* The new angle, in radians
*/
public void setPolar(final double r, final double t) {
super.setLocation(r * Math.cos(t), r * Math.sin(t));
}

/** Sets the vector's radius, preserving its angle. */
public void setR(final double r) {
final double t = getTheta();
setPolar(r, t);
}

/** Sets the vector's angle, preserving its radius. */
public void setTheta(final double t) {
final double r = getR();
setPolar(r, t);
}

/** The sum of the vector and rhs */
public Vec2D plus(final Vec2D rhs) {
return new Vec2D(x + rhs.x, y + rhs.y);
}

/** The difference of the vector and rhs: this - rhs */
public Vec2D minus(final Vec2D rhs) {
return new Vec2D(x - rhs.x, y - rhs.y);
}

public boolean equals(final Vec2D rhs) {
return x == rhs.x && y == rhs.y;
}

/** Product of the vector and scalar */
public Vec2D multiply(final double scalar) {
return new Vec2D(scalar * x, scalar * y);
}

/** Dot product of the vector and rhs */
public double dotProduct(final Vec2D rhs) {
return x * rhs.x + y * rhs.y;
}

/**
* Since Vector2D works only in the x-y plane, (u x v) points directly along
* the z axis. This function returns the value on the z axis that (u x v)
* reaches.
*
* @return signed magnitude of (this x rhs)
*/
public double crossProduct(final Vec2D rhs) {
return x * rhs.y - y * rhs.x;
}

/** Product of components of the vector: compenentProduct( <x y>) = x*y. */
public double componentProduct() {
return x * y;
}

/** Componentwise product: <this.x*rhs.x, this.y*rhs.y> */
public Vec2D componentwiseProduct(final Vec2D rhs) {
return new Vec2D(x * rhs.x, y * rhs.y);
}

/**
* An alias for getR()
*
* @return the length of this
*/
public double length() {
return getR();
}

/**
* Returns a new vector with the same direction as the vector but with
* length 1, except in the case of zero vectors, which return a copy of
* themselves.
*/
public Vec2D unitVector() {
double length = getR();
if (length != 0)
return new Vec2D(x / length, y / length);
return new Vec2D(0, 0);
}

/** Polar version of the vector, with radius in x and angle in y */
public Vec2D toPolar() {
return new Vec2D(Math.sqrt(x * x + y * y), Math.atan2(y, x));
}

/** Rectangular version of the vector, assuming radius in x and angle in y */
public Vec2D toRect() {
return new Vec2D(x * Math.cos(y), x * Math.sin(y));
}

/** @return Standard string representation of a vector: "<x, y>" */
@Override
public String toString() {
return "<" + x + ", " + y + ">";
}
}

最佳答案

force.plus(n.above.location.minus(n.location).multiply(FRICTION_COEF));

您只需通过摩擦系数缩放力。摩擦不是这样运作的。您必须计算阻尼力作为节间速度(不是距离)的函数并将其从弹力中减去,或者通过从弹力中减去固定量来应用静摩擦。

关于java - 二维绳索模拟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31417430/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com