我有两个圆圈,一个是我移动的,另一个在屏幕中央。我想做的是,当我移动一个到另一个时,圆不会重叠。我设法做了一些类似的事情,但这很可怕,我想知道是否有更有效的方法来做。

public class Juego extends SurfaceView implements View.OnTouchListener{

private Paint paint;
int x = 100, y = 100, radio = 100, otroX, otroY;

public Juego(Context context, AttributeSet attrs) {
    super(context, attrs);
    this.setOnTouchListener(this);
    setFocusable(true);
    paint = new Paint();
}

public void onDraw(Canvas canvas) {

    paint.setColor(Color.WHITE);
    canvas.drawRect(0, 0, getWidth(), getHeight(), paint);

    paint.setColor(Color.BLACK);
    canvas.drawCircle(x, y, radio, paint);

    otroX = canvas.getWidth() / 2;
    otroY = canvas.getHeight() / 2;

    canvas.drawCircle(otroX, otroY, radio, paint);

    invalidate();
}

@Override
public boolean onTouch(View view,MotionEvent motionEvent){

    x = (int)motionEvent.getX();
    y = (int)motionEvent.getY();

    double dist = Math.sqrt(Math.pow((x - otroX), 2) + Math.pow((y - otroY), 2));

    if (dist <= radio + radio) {

        if (x < otroX) {
            x = otroX - radio - (radio / 2);
        }
        if (x > otroX) {
            x = otroX + radio + (radio / 2);
        }
        if (y < otroY) {
            y = otroY - radio - (radio / 2);
        }
        if (y > otroY) {
            y = otroY + radio + (radio / 2);
        }
    }

    invalidate();
    return true;
}

}
这就是我所拥有的:https://mega.nz/#!HZsVhR4L!v6AhTWgJ27U8vV1rYJ_BuO8O2TxgKJV113m58P6ANek
这就是我想要的:https://mega.nz/#!PJFHmDYR!auzX-L-TBTNCZuD8vX8ugUeZmi-HhtWLqs6mUilfW_M

最佳答案

要解决这个问题,当移动圆太近时,我们需要在由两个圆中心定义的直线上以预期的最小距离移动:

@Override
public boolean onTouch(View view, MotionEvent motionEvent) {

    x = (int) motionEvent.getX();
    y = (int) motionEvent.getY();

    double dist = Math.sqrt(Math.pow((x - otroX), 2) + Math.pow((y - otroY), 2));

    if (dist <= radius * 2) {
        // This calculate the displacement of a the distance 'radius*2' on the line between the two circles centers.
        double angle = Math.atan2(y - otroY, x - otroX);
        int moveX = (int) ((radius * 2) * Math.cos(angle));
        int moveY = (int) ((radius * 2) * Math.sin(angle));
        // Then we need to add the displacement to the coordinates of the origin to have the new position.
        x = otroX + moveX;
        y = otroY + moveY;
    }

    invalidate();
    return true;
}

此代码基于KazenoZ answer

10-08 13:46