2つのボールの衝突をシミュレートします。一方は加速度計で制御され、もう一方はランダムに動きます。 これらの衝突を実装するにはどうすればよいですか?私はボールと衝突の条件を設定することができましたが、それを超えて、どのようにして衝突ベクトルを表現できるか分かりません。アルゴリズムやヒントが分かるでしょう:)私はxとyの速度と変数に格納された2つのボールの位置を持っています。私はまた、いくつかの基本的な(しかし間違った)衝突メカニズムを使用することに成功しました。ランダムな動きのボールは、そのxとyの速度を逆転させます。しかし、ボールがあまりに速く動いていると、ボールが重なってしまっても問題は発生しています。私は何をしますか?2つのボールの衝突
package perseus.gfx.test;
import everything;
public class Ball extends View {
RectF lol;
Paint paint, lpaint;
Bitmap bitmap;
Canvas canvas;
private float ballx = 150;
private float bally = 140;
private double speedx = 0;
private double speedy = 0; //ignore
private double accx, accy=0;
private float rad = 15;
private float mult = 0.5f;
private float friction = -0.001f;
private double xv, yv, xS, yS;
private long ltm = -1;
int width, height;
int xmax, ymax;
int xmin, ymin;
public Ball(Context context) {
super(context);
lol = new RectF();
paint = new Paint();
paint.setColor(Color.CYAN);
lpaint = new Paint();
lpaint.setColor(Color.GRAY);
}
public double getSpeedX()
{
return this.speedx;
}
public double getSpeedY()
{
return this.speedy;
}
public void setSpeedX(double x)
{
this.speedx = x;
}
public void setSpeedY(double y)
{
this.speedy = y;
}
public void setColor(int c)
{
paint.setColor(c);
}
public float getRad()
{
return this.rad;
}
public void setRad(float rad)
{
this.rad = rad;
}
public void setAX(double accx)
{
this.accx = accx;
}
public void setAY(double accy)
{
this.accy = accy;
}
public float getX()
{
return this.ballx;
}
public void setX(float ballx)
{
this.ballx = ballx;
}
public float getY()
{
return this.bally;
}
public void setY(float bally)
{
this.bally = bally;
}
public void moveBall() {
xv = accx * mult;
yv = accy * mult;
ballx -= xv * mult;
bally -= yv * mult;
ballx +=speedx;
bally +=speedy;
/*ballx +=speedx;
bally +=speedy;*/
// Collision detection
if (ballx + rad > xmax) {
speedx = -speedx;
ballx = xmax-rad;
}
else if (ballx - rad < 0) {
speedx = -speedx;
ballx = rad;
}
if (bally + rad > 2*ymax/3) {
speedy = -speedy;
bally = 2*ymax/3 - rad;
}
else if (bally - rad < 0) {
speedy = -speedy;
bally = rad;
}
try {
Thread.sleep(20);
} catch(InterruptedException e) {}
invalidate();
}
@Override
public void onMeasure(int widthM, int heightM)
{
width = View.MeasureSpec.getSize(widthM);
height = View.MeasureSpec.getSize(heightM);
xmax = width-1;
ymax = height-1;
xmin = 0;
ymin = 0;
setMeasuredDimension(width, height);
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
canvas = new Canvas(bitmap);
}
@Override
public void onDraw(Canvas canvas)
{
canvas.drawBitmap(bitmap, 0, 0, paint);
lol.set(ballx - rad, bally-rad, ballx + rad, bally+rad);
canvas.drawLine(0, 2*height/3, width, 2*height/3, lpaint);
/*canvas.drawOval(lol, paint);*/
canvas.drawCircle(ballx, bally, rad, paint);
canvas.drawText(xv + " " + yv, 0, height/2, lpaint);
canvas.save();
moveBall();
canvas.restore();
}
}
これは私のボールクラスであり、そして私の主な活動は次のようになります。
package perseus.gfx.test;
import everything;
public class GfxActivity extends Activity implements OnSeekBarChangeListener, OnItemSelectedListener, SensorEventListener {
ViewGroup.LayoutParams vg = new ViewGroup.LayoutParams(-1, -1);
double velx, vely;
double x, y;
float radi;
double finx, finy;
float finrad;
long lastSensorUpdate = -1;
SensorManager sm;
static double ux, uy; //initial ball velocity
SeekBar velo, rad;
Spinner colour;
Ball ball, tester;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ball = new Ball(this);
tester = new Ball(this);
setContentView(R.layout.main);
addContentView(ball, vg);
addContentView(tester, vg);
sm = (SensorManager)getSystemService(SENSOR_SERVICE);
sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_ORIENTATION), SensorManager.SENSOR_DELAY_GAME);
colour = (Spinner)findViewById(R.id.color);
colour.setOnItemSelectedListener(this);
ArrayAdapter<CharSequence> aa = ArrayAdapter.createFromResource(this, R.array.colors, android.R.layout.simple_spinner_item);
aa.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
colour.setAdapter(aa);
velo = (SeekBar)findViewById(R.id.vel);
velo.setOnSeekBarChangeListener(this);
rad = (SeekBar)findViewById(R.id.rad);
rad.setOnSeekBarChangeListener(this);
ux = ball.getSpeedX();
uy = ball.getSpeedY();
radi = ball.getRad();
tester.setSpeedX(5);
tester.setSpeedY(3);
tester.setX(0);
tester.setY(0);
tester.setColor(Color.DKGRAY);
}
@Override
public void onProgressChanged(SeekBar seeker, int arg1, boolean arg2) {
switch(seeker.getId())
{
case R.id.vel:
x = ball.getSpeedX();
y = ball.getSpeedY();
if(x<0)
finx = -ux-arg1;
else if(x >= 0)
finx = ux+arg1;
if(y<0)
finy = -uy-arg1;
else if(finy>=0)
finy = uy+arg1;
ball.setSpeedX(finx);
ball.setSpeedY(finy);
break;
case R.id.rad:
finrad = radi + arg1;
ball.setRad(finrad);
break;
}
}
@Override
public void onStartTrackingTouch(SeekBar arg0) {
//nothing lol
}
@Override
public void onStopTrackingTouch(SeekBar arg0) {
//nothing lol
}
@Override
public void onItemSelected(AdapterView<?> parent, View v, int position,
long id) {
switch(position)
{
case 0:
ball.setColor(Color.CYAN);
break;
case 1:
ball.setColor(Color.RED);
break;
case 2:
ball.setColor(Color.BLUE);
break;
case 3:
ball.setColor(Color.GREEN);
break;
}
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
}
@Override
public void onAccuracyChanged(Sensor arg0, int arg1) {
// TODO Auto-generated method stub
}
@Override
public void onSensorChanged(SensorEvent sensorevent) {
if(sensorevent.sensor.getType() == Sensor.TYPE_ORIENTATION)
{
ball.setAX(sensorevent.values[2]);
ball.setAY(sensorevent.values[1]);
}
if((Math.pow(ball.getX() - tester.getX(), 2) + Math.pow(ball.getY() - tester.getY(), 2)) <= (ball.getRad() + tester.getRad())*(ball.getRad() + tester.getRad()))
{
/*tester.setSpeedX(-1*tester.getSpeedX());
tester.setSpeedY(-1*tester.getSpeedY());*/
}
}
}
ボールとテスターは、私の2つのボール、ボールが加速度計によって制御されています。私はこのコードがあまり効率的ではないことを知っていますが、私はまず衝突を実装するつもりだと思っています。
まあ、私はそれらを両方とも同じ質量として扱いたいと言っていたことを忘れていました。私は自分のコードを投稿しました。 –
質量を同じように扱うと、運動量方程式の保存が簡単になりますが、運動エネルギーが保存されているかどうかにかかわらず、弾性または非弾性のどちらの衝突であるかを決定する必要があります。 衝突検出の他の問題について、私が気づく最初のことは、ボールを移動した後に衝突検出を行うことです。これは、問題の一部である可能性があります.2つのボールがちょうど交差するときに、それらを互いに近づけると衝突する可能性があります。 – ose
私は弾性衝突を望んでいました。私は衝突検出コードをどこに置くことをお勧めしますか? –