如何找到点击的绝对位置,而在放大 [英] How to find absolute position of click while zoomed in

查看:363
本文介绍了如何找到点击的绝对位置,而在放大的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请参见下面的每个部分我的问题在三个独立的方式描述说明。希望应该帮助的人来回答。

Please see each section below for a description of my problem described in three separate ways. Hopefully should help people to answer.

问题:如何找到一对坐标pssed在画布/用户空间EX $ P $的时候,你只需要在坐标前pssed在缩放图像方面$ P $,在给定初始刻度点和放大器;比例系数?

Problem: How do you find a pair of coordinate expressed in canvas/userspace when you only have the coordinate expressed in terms of a zoomed image, given the original scale point & scale factor?

在实践中的问题:

目前,我正在试图复制应用程序中使用的变焦功能,如画廊/地图时,你可以捏放大/缩小的变焦走向捏的中点。

I'm currently trying to replicate the zoom functionality used in apps such as the gallery / maps, when you can pinch to zoom/zoom out with the zoom moving towards the midpoint of the pinch.

在向下我省变焦的中心点(这是在X,Y坐标基于当前屏幕上)。然后,我有被检测出规模化的手势时,此功能的行为:

On down I save the centre point of the zoom (which is in X,Y coordinates based on the current screen). I then have this function act when a "scale" gesture is detected:

class ImageScaleGestureDetector extends SimpleOnScaleGestureListener {
    @Override
    public boolean onScale(ScaleGestureDetector detector) {
        if(mScaleAllowed) 
            mCustomImageView.scale(detector.getScaleFactor(), mCenterX, mCenterY);
        return true;
    }
}   

在CustomImageView的比例函数是这样的:

The scale function of the CustomImageView look like this:

public boolean scale(float scaleFactor, float focusX, float focusY) {
    mScaleFactor *= scaleFactor;

    // Don't let the object get too small or too large.
    mScaleFactor = Math.max(MINIMUM_SCALE_VALUE, Math.min(mScaleFactor, 5.0f));

    mCenterScaleX = focusX;
    mCenterScaleY = focusY;

    invalidate();

    return true;
}

缩放图像的绘制是通过覆盖的OnDraw方法,尺度围绕中心阿富汗国家发展战略画在画布上取得的形象吧。

The drawing of the scaled image is achieved by overriding the onDraw method which scales the canvas around the centre ands draw's the image to it.

@Override
public void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    canvas.save();
    canvas.translate(mCenterScaleX, mCenterScaleY);
    canvas.scale(mScaleFactor, mScaleFactor);
    canvas.translate(-mCenterScaleX, -mCenterScaleY);
    mIcon.draw(canvas);
    canvas.restore();
}

这所有的比例因子1的比例时工作得很好,这是因为最初mCenterX和mCenterY是这是基于在设备屏幕上的坐标。 10,10在设备上为10,10在画布上。

This all works fine when scaling from ScaleFactor 1, this is because the initial mCenterX and mCenterY are coordinates which are based on the device screen. 10, 10 on the device is 10, 10 on the canvas.

在你已经然而缩放,那么下一次你点击的位置10,10将不再对应10,10,因为缩放和放大器的画布;已被执行的变换。

After you have already zoomed however, then next time you click position 10, 10 it will no longer correspond to 10, 10 in the canvas because of the scaling & transforming that has already been performed.

抽象问题:

下面的图像是围绕中心点A的变焦操作的一个例子的每个框重新presents视图的位置和大小时,在该换算系数(1,2,3,4,5)。

The image below is an example of a zoom operation around centre point A. Each box represents the position and size of the view when at that scale factor (1, 2, 3, 4, 5).

在例如,如果通过2周围甲则点击位置B上的因子缩放,在X,Y报告为乙将基于屏幕上的位置 - 不上的相对位置的初始的0,0画布上。

In the example if you scaled by a factor of 2 around A then you clicked on position B, the X, Y reported as B would be based on the screen position - not on the position relative to 0,0 of the initial canvas.

我需要找得到B的绝对位置的方法。

I need to find a way of getting the absolute position of B.

推荐答案

所以,重绘我发现我一直在寻找解决这个问题后。它是通过一些反复的走了,但在这里就是我的工作了:

So, after redrawing the problem I've found the solution I was looking for. It's gone through a few iteration's but here's how I worked it out:

B - 点,规模化经营的中心

B - Point, Center of the scale operation

A1,A2,A3 - 点,在用户空间相等,但不同的画布空间

A1, A2, A3 - Points, equal in user-space but different in canvas-space.

您知道的Bx值,因为他们总是不断的无论什么比例因子(你知道在两个帆布空间和在用户空间)该值。

You know the values for Bx and By because they are always constant no matter what the scale factor (You know this value in both canvas-space and in user-space).

您知道&放大器; 在用户空间,所以你可以找到 Bx的之间的距离。这种测量是在用户空间,将其转换为一个帆布空间测量简单地通过比例因子除以它。 (一旦转化为画布空间,你可以看到这几行红色,橙色和黄色)。

You know Ax & Ay in user-space so you can find the distance between Ax to Bx and Ay to By. This measurement is in user-space, to convert it to a canvas-space measurement simply divide it by the scale factor. (Once converted to canvas-space, you can see these lines in red, orange and yellow).

As点 B 是恒定的,它之间的距离,并且边缘常数(这些被重新由蓝线psented $ P $)。此值等于在用户空间和帆布空间。

As point B is constant, the distance between it and the edges are constant (These are represented by Blue Lines). This value is equal in user-space and canvas-space.

您减去这两个帆布空间测量( Bx的 Bx的边缘)从你留下的坐标点A的总宽度帆布空间

You know the width of the Canvas in canvas-space so by subtracting these two canvas space measurements (Ax to Bx and Bx to Edge) from the total width you are left with the coordinates for point A in canvas-space:

public float[] getAbsolutePosition(float Ax, float Ay) {

    float fromAxToBxInCanvasSpace = (mCenterScaleX - Ax) / mScaleFactor;
    float fromBxToCanvasEdge = mCanvasWidth - Bx;
    float x = mCanvasWidth - fromAxToBxInCanvasSpace - fromBxToCanvasEdge;

    float fromAyToByInCanvasSpace = (mCenterScaleY - Ay) / mScaleFactor;
    float fromByToCanvasEdge = mCanvasHeight - By;
    float y = mCanvasHeight - fromAyToByInCanvasSpace - fromByToCanvasEdge;

    return new float[] { x, y };
}

当你点击到原来的中心左上方以上code和形象描述。我用同样的逻辑来找到一个无论哪个象限它位于和重构为以下内容:

The above code and image describe when you're clicking to the top left of the original centre. I used the same logic to find A no matter which quadrant it was located in and refactored to the following:

public float[] getAbsolutePosition(float Ax, float Ay) {

    float x = getAbsolutePosition(mBx, Ax);
    float y = getAbsolutePosition(mBy, Ay); 

    return new float[] { x, y };
}

private float getAbsolutePosition(float oldCenter, float newCenter, float mScaleFactor) {
    if(newCenter > oldCenter) {
        return oldCenter + ((newCenter - oldCenter) / mScaleFactor);
    } else {
        return oldCenter - ((oldCenter - newCenter) / mScaleFactor);
    }
}

这篇关于如何找到点击的绝对位置,而在放大的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆