使用 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
}
我在 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
}