使用 Processing 和 box2d 创建单个 wave

Creating a single wave with Processing and box2d

我在 box2d 世界中有一系列的物体。这些身体被锁在一起。我想在按下鼠标时沿着身体创建一个正弦波。我只希望这个波发生一次,它应该以相同的幅度沿着物体的长度继续,直到它到达终点,然后停止,直到再次按下鼠标。

目前我有这个:

float angle = 0.0;
float scalar = 1.2;
float speed = 0.01;
void mousePressed() {  
    for (int j = 0; j < 91; j++) {
        float x = sin(j+angle)*scalar;  
        float y = 0;       
        Vec2 mov2 = new Vec2(x,y);
        bridge.particles.get(j).body.setLinearVelocity(mov2);   
        angle+=speed;
  }
}

然而,这会导致身体变成一个连续的波浪,如下图所示向外扩展(目前只在左链上尝试):

我怎样才能像描述的那样创建一个向下移动的单波?

使用我使用的@dfour 修改后的代码:

void mousePressed() { 
     int frequency = 10; // sine frequency (larger for longer wave)
    double fullCircle = Math.toRadians(180); // get 1 full iteration of a circle in radians;
    float x=0;
    float y=0;
    for(int i = 0; i < 100 ; i++){
        if(i > fullCircle*frequency){
            // after first wave so output 0
            //System.out.println(0); 
        }else{
            // part of first sinewave so output wave value
            x =(float)Math.sin(i/frequency);
            Vec2 mov2 = new Vec2(x,y);
            print(" x: "+x);
            System.out.println(Math.sin(i/frequency));
            bridge.particles.get(i).body.setLinearVelocity(mov2);
        }
    }
}

但这给了我以下信息,波浪实际上并没有沿着实体线前进:

为了从正弦波中获取单个波,您只需要循环一次,一旦第一个波完成输出 0;

    int frequency = 10; // sine frequency (larger for longer wave)
    double fullCircle = Math.toRadians(360); // get 1 full iteration of a circle in radians;
    for(double i = 0; i < 75 ; i++){
        if(i > fullCircle*frequency){
            // after first wave so output 0
            System.out.println(0); 
        }else{
            // part of first sinewave so output wave value
            System.out.println(Math.sin(i/frequency));
        }
    }

编辑:

我已经使用 LibGdx 框架对此进行了测试,一切正常。要将此应用于您的代码,您需要添加一个计时器字段来存储时间:

private float sineTimer = 50f; //initially 50f as 0 would start wave
private final int PARTICLES = 40; // the amount of particles in your bridge

然后在你的点击方法中添加:

sineTimer = -35f; // resets timer 

现在在你的主循环中添加:

sineTimer += Gdx.graphics.getDeltaTime() * 10; // increment time since last frame

    int frequency = 3; // sine frequency (larger for longer wave)
    float fullCircle = (float) Math.toRadians(360); // get 1 full iteration of a circle in radians;
    // loop through all particles
    for(int i = 0; i < PARTICLES ; i++){
        float offset = i; // set base offset
        offset+=sineTimer; // add timer value to offset
        // if offset is lower than 0 or past first sine wave set particle to default place
        if(offset > fullCircle*frequency || offset < 0){
            bridgeParticles.get(i).setTransform(32,i, 0);
        }else{ // else apply sine position (I used x*3 here to amplifiy sine on x axis)
            float x =(float)Math.sin(offset/frequency);
            bridgeParticles.get(i).setTransform((x *3) + 32, i, 0);

        }
    }

针对处理环境修改的代码:

private float sineTimer = 50f; //initially 50f as 0 would start wave
private final int PARTICLES = 40; // the amount of particles in your bridge

void draw(){
     sineTimer += 0.5; // increment time since last frame

        int frequency = 23; // sine frequency (larger for longer wave)
        float fullCircle = (float) Math.toRadians(180); 
        for(int i = 0; i < PARTICLES ; i++){
            float offset = i; // set base offset
            offset+=sineTimer; // add timer value to offset
            if(offset > fullCircle*frequency || offset < 0){
                bridge.particles.get(i).body.setTransform(box2d.coordPixelsToWorld(200,i*10), 0);
            }else{ 
                float x =(float)Math.sin(offset/frequency);
                bridge.particles.get(i).body.setTransform(box2d.coordPixelsToWorld((x *125) +200, i*10), 0);
            }
        } 
    }

    void mousePressed() { 
    sineTimer = -35f; // resets timer 
    }