Система координат холста Android - PullRequest
4 голосов
/ 28 мая 2010

Я пытаюсь найти информацию о том, как изменить систему координат для холста. У меня есть некоторые векторные данные, которые я хотел бы нарисовать на холсте, используя такие вещи, как круги и линии, но система координат данных не соответствует системе координат холста.

Есть ли способ сопоставить используемые мной единицы измерения с единицами измерения на экране?

Я рисую в ImageView, который не занимает весь экран.

Если мне нужно выполнять свои собственные вычисления перед каждым вызовом рисования, как мне найти ширину и высоту моего ImageView?

Кажется, что вызовы getWidth () и getHeight (), которые я пытался вернуть, возвращают весь размер холста, а не размер ImageView, что не помогает.

Я вижу некоторые матричные вещи, это то, что будет работать для меня?

Я пытался использовать «общедоступный масштаб пустот (float sx, float sy)», но это больше похоже на масштабирование на уровне пикселей, а не на функцию векторного масштабирования путем расширения каждого пикселя. Это означает, что если размеры увеличиваются, чтобы соответствовать экрану, толщина линии также увеличивается.


Обновление:

После некоторых исследований я начинаю думать, что нет способа изменить систему координат на что-то другое. Мне нужно сопоставить все мои координаты с пиксельными координатами экрана и сделать это, изменив каждый вектор. GetWidth () и getHeight () теперь работают лучше для меня. Я могу сказать, что было не так, но я подозреваю, что не могу использовать эти методы внутри конструктора.

Ответы [ 3 ]

2 голосов
/ 13 июня 2010

Спасибо за ответ. Я почти отказался от того, чтобы заставить это работать так, как я думаю. Конечно, как я думаю, что вещи должны происходить, не так, как они случаются. :)

Вот, в основном, как это работает, но в некоторых случаях кажется, что в некоторых случаях оно не совпадает с пикселем, и круги, кажется, пропускают участки, когда вещи попадают в некоторые граничные условия, которые мне еще предстоит выяснить. Лично я думаю, что это недопустимо, чтобы быть внутри кода приложения и должно быть в библиотеках Android ... подмигнуть, подтолкнуть, если вы работаете на Google. :)

private class LinearMapCanvas
{
    private final Canvas canvas_; // hold a wrapper to the actual canvas.

    // scaling and translating values:
    private double scale_;

    private int translateX_;
    private int translateY_;

// linear mapping from my coordinate system to the display's:
    private double mapX(final double x)
    {
    final double result = translateX_ + scale_*x;
    return result;
    }

    private double mapY(final double y)
    {
        final double result = translateY_ - scale_*y;
        return result;
    }

    public LinearMapCanvas(final Canvas canvas)
    {
        canvas_ = canvas;

// Find the extents of your drawing coordinates:
        final double minX = extentArray_[0];
    final double minY = extentArray_[1];
    final double maxX = extentArray_[2];
    final double maxY = extentArray_[3];

// deltas:
    final double dx = maxX - minX;
    final double dy = maxY - minY;

// The display's available pixels, accounting for margins and pen stroke width:
    final int width = width_ - strokeWidth_ - 2*margin_;
    final int height = height_ - strokeWidth_ - 2*margin_;

    final double scaleX = width / dx;
    final double scaleY = height / dy;

    scale_ = Math.min(scaleX , scaleY); // Pick the worst case, so the drawing fits

// Translate so the image is centered:
        translateX_ = (int)((width_ - (int)(scale_*dx))/2.0 - scale_*minX);
        translateY_ = (int)((height_ - (int)(scale_*dy))/2.0 + scale_*maxY);
    }

// wrappers around the canvas functions you use.  These are only two of many that would need to be wrapped.  Annoying and error prone, but beats any alternative I can find.
    public void drawCircle(final float cx, final float cy, final float radius, final Paint paint)
    {
    canvas_.drawCircle((float)mapX(cx), (float)mapY(cy), (float)(scale_*radius), paint);
    }

    public void drawLine(final float startX, final float startY, final float stopX, final float stopY, final Paint paint)
    {
    canvas_.drawLine((float)mapX(startX), (float)mapY(startY), (float)mapX(stopX), (float)mapY(stopY), paint);
    }
...
}
0 голосов
/ 16 апреля 2011

Вы можете масштабировать координаты холста в своих единицах измерения, используя метод preScale() матрицы холста. Имейте в виду, однако, что это также масштабирует ширину обводки Paint, которая может быть не тем, что вы хотите.

0 голосов
/ 11 июня 2010

Единственный известный мне способ создания пользовательской векторной графики на лету в Android - это нарисовать все в файл изображения и затем поместить его в ImageView. Я не уверен, что точно понимаю, о чем вы спрашиваете, но если единственной проблемой является масштабирование, ImageView будет масштабировать любое изображение, которое ему дается, до его собственного размера, используя android:scaleType="center" как свойство ImageView.

Что касается изменения системы координат, я сомневаюсь, что это возможно (хотя я не исследовал это). Впрочем, написать функцию, которая бы отображала систему ваших данных на стандартную систему координат Android, было бы довольно тривиально.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...