Рисование на холсте — не рисование поверх других элементов

Моя проблема довольно проста, я думаю.

Я хочу нарисовать точку на холсте, как только прикоснусь к ней. Точка будет нарисована в том месте, к которому я прикасаюсь. Далее я хочу нарисовать еще одну точку на экране, но не на месте первой точки. Значит, я хочу предотвратить рисование изображения поверх другого изображения.

Я попытался заархивировать это с помощью следующего кода:

Класс активности

    public class Draw extends Activity {
    DrawView drawView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Set full screen view
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
                                         WindowManager.LayoutParams.FLAG_FULLSCREEN);
        requestWindowFeature(Window.FEATURE_NO_TITLE);

        drawView = new DrawView(this);
        setContentView(drawView);
        drawView.requestFocus();
    }
}

Класс холста

    public class DrawView extends View implements OnTouchListener {
    private static final String TAG = "DrawView";

    List<Point> points = new ArrayList<Point>();
    Vector<Bitmap> bitmaps = new Vector<Bitmap>();
    Paint paint = new Paint();


    public DrawView(Context context) {
        super(context);
        setFocusable(true);
        setFocusableInTouchMode(true);

        this.setOnTouchListener(this);
    }

    @Override
    public void onDraw(Canvas canvas) {
        canvas.drawColor(Color.WHITE);
        for (Point point : points) {
            canvas.drawBitmap(bitmaps.get(point.i), point.x, point.y, paint);
        }
    }

    public boolean onTouch(View view, MotionEvent event) {
        Log.d("Touch","Touch");
        Log.d("Points", "" + points.size());
        Log.d("Bitmaps", "" + bitmaps.size());

        int i = 0;
        for (Point point : points) {
            int height = bitmaps.get(i).getHeight();
            int width = bitmaps.get(i).getWidth();
            //Log.d("dimensions", height + ", " + width);

            for (int x = 0; x <= width; x++) {
                if (Math.floor(point.x + x) == Math.floor(event.getX())) {
                    points.get(i).isTaken = true;
                    Log.d("isTakenX", "" + point.isTaken);
                    break;
                }
                for (int y = 0; y <= height; y++) {
                    if (Math.floor(point.y + y) == Math.floor(event.getY())) {
                        points.get(i).isTaken = true;
                        Log.d("isTakenY", "" + point.isTaken);
                        break;
                    }
                }
            }
            i++;
        }
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            Log.d("EventDown","DOWN");
            boolean isTaken = false;
            for (Point point : points) {
                if (point.isTaken) {
                    isTaken = true;
                }
            }
            if (!isTaken) {
                bitmaps.add(BitmapFactory.decodeResource(getResources(), R.drawable.greenstar));
                Point point = new Point();
                point.x = event.getX();
                point.y = event.getY();
                point.i = bitmaps.size() - 1;
                points.add(point);
                //Log.d("pointClick",point.toString());
                invalidate();
                return true;
            }
        }
        return false ;
    }
}

    class Point {
        float x, y;
        int i;
        boolean isTaken = false;

        @Override
        public String toString() {
            return i + ": " + x + ", " + y;
        }
    }

В методе onTouch вы можете увидеть, как я определяю положение изображения, которое я не хочу перерисовывать. Я сохраняю все изображения и их точки, которые я рисую, в списки, чтобы иметь возможность их изменять. Затем я проверяю, сколько места занимает изображение на экране, и щелкнул ли я только по этому месту.

Однако после того, как первое изображение было нарисовано на холсте, я не могу нарисовать еще одно. Похоже, программа застряла на "isTaken". Возможно, мой логарифм о том, как проверить, занято ли место, неверен. Однако не могу понять, что не так.

У тебя есть идея?

Заранее спасибо


person Sebastian    schedule 09.08.2012    source источник


Ответы (1)


ладно несколько моментов. Одна логическая ошибка и несколько улучшений. (код и идея)

Во-первых: когда вы используете конструкцию foreach, используйте переменную из цикла (например, точку) для доступа к экземпляру из списка, который вы зацикливаете. Так что замените свой points.get(i) простым point.

Во-вторых: поскольку у вас есть круг, вам не нужно проверять, находится ли точка в прямоугольнике (я полагаю, это то, чего вы хотите достичь). Проверьте, достаточно ли велико расстояние между центрами двух точек (тех, что уже нарисованы, и новой, которую нужно нарисовать). Используйте для этого уравнение Пифагора (c^2 = a^2 * b^2).

В-третьих (фактическая ошибка): ваша логика двух циклов for неверна, вы обрабатываете x и y отдельно, но вы должны проверять их вместе. Вам не нужны циклы for для достижения того, чего вы хотите.

Измените циклы for на:

if(Math.pow(radius*2,2) > Math.pow(event.getX-point.x,2)+Math.pow(event.getY-point.Y, 2))
        point.isTaken = true;

Где радиус - это радиус нарисованного круга. Попробуйте это с этим и сообщите, если у вас возникнут дополнительные проблемы.

person RaphMclee    schedule 09.08.2012
comment
Эй, спасибо за помощь. На самом деле я собираюсь рисовать квадраты (позже квадратные изображения) на экране, извините за неправильную информацию. Первое предложение: пробовал это раньше, изменил его, потому что я получил исключение из-за другой ошибки. Второе предложение: Спасибо, это поможет мне и с квадратами! Я должен проверить расстояние между верхними левыми границами старого и нового квадрата. Третье предложение: я сам только что понял эту ошибку. Однако нет необходимости проверять это, если я просто измерю расстояние между старым и новым квадратом. Большое тебе спасибо. - person Sebastian; 09.08.2012
comment
np, если возникнут новые проблемы, просто сообщите об этом SO. - person RaphMclee; 10.08.2012
comment
Работал с вашими идеями. Спасибо! Я думаю, что мой мозг просто застрял сегодня :/ - person Sebastian; 10.08.2012