【问题标题】:Converting a coordinate from one space to another将坐标从一个空间转换到另一个空间
【发布时间】:2012-01-25 20:54:40
【问题描述】:

我似乎在这里有点数学失败......我需要将一个(x,y)点从一个坐标空间转换到另一个坐标空间 - 不是从极坐标到笛卡尔或任何类似的意义上。 ..只是从一个绑定到另一个。即,对于落在左下角(-100,-100)和右上角(100,100)的矩形中的特定(x,y),我需要找出该点在左下角(0 ,0) 和右上角 (500, 500)。

我觉得这只是简单的数学运算,但我花了很长时间才把它弄对......

这是一个用java编写的小型计算机图形程序。本质上,有一个剪辑窗口会发生变化,并且该剪辑窗口需要填满整个视图窗口。剪辑和视图的初始值由上述矩形按顺序给出。但是,剪辑可能会更改为,例如,左下角 (-80, -65) 和右上角 (75, 65) 的矩形。然后,我需要将该矩形内的点转换为视图窗口内的点(左下 (0,0),右上 (500, 500))

这是我现在所拥有的:

public int normalizeX(float x) {
    float clipWidth = clipRight - clipLeft;
    int viewWidth = viewRight - viewLeft;
    x += 100; //Get x into range [0, 200] instead of [-100, 100]
    //First convert x to value within clip width, then "scale" to viewport width
    return (int)(((clipWidth*x)/200) * (viewWidth/clipWidth));
}

public int normalizeY(float y) {
    float clipHeight = clipTop - clipBottom;
    int viewHeight = viewTop - viewBottom;
    y += 100; //Get y into range [0, 200] instead of [-100, 100]
    //First convert y to value within clip height, then "scale" to viewport height
    return (int)(((clipHeight*y)/200) * (viewHeight/clipHeight));
}

感谢您的帮助!

【问题讨论】:

  • 硬编码的[0, 200][-100, 100]是从哪里来的?
  • 感谢吉恩的提醒。 James,这些值来自这样一个事实,即所有形状,无论是剪辑或视图窗口,都定义在 (-100, -100), (100, 100) 范围内。

标签: java math coordinate


【解决方案1】:

假设您的旧界限是 xLoOldxHiOld(在您的示例中分别为 -80 和 75),而您的新界限是 xLoNewxHiNew(在您的示例中分别为 0 和 500) ,然后您可以将您的 xOld 标准化为您的新坐标系,如下所示:

xNew = (xOld-xLoOld) / (xHiOld-xLoOld) * (xHiNew-xLoNew) + xLoNew

对 y 也是一样。

【讨论】:

  • 最后一位不应该是+ xLoNew吗?
  • 啊,是的,我正要提到这一点,但有人打败了我:-p 谢谢!
  • {xLoOld} 你对那些变量名是认真的吗? :)
  • 死得很严重。但无论如何,请用你严肃的变量名来启发我们,学究! ;-)
【解决方案2】:

这样的事情可能会对您有所帮助。

    public static float scale(
           float x,
           float old_min, float old_max,
           float new_min, float new_max)
    {
        float old_range = old_max - old_min;
        float new_range = new_max - new_min;
        return new_min + (x - old_min) * new_range / old_range;
    }

您需要在两个维度上缩放坐标。我省略了其他计算,例如转换为 int 等。

我还建议创建合适的类型,例如 RegionRectangle,以通过至少减少此函数的参数数量来简化代码。

【讨论】:

  • 谢谢!并且区域矩形的东西不是问题。旧边界和新边界在使用 setter 方法更改的全局变量中维护。感谢您的帮助!
【解决方案3】:

非常简单:您想要一个将 -100 映射到 0 和 100 到 500 的转换。或者盲目地将 [-100, 100] 范围映射到 [0, 500] 范围:

[-100, 100] ----> [0, 500]

第一步是将范围 [-100, 100] 转换为 [0, 200]:

x ----> x + 100

下一步是将范围 [0, 200] 转换为 [0, 500]

x ----> x * 500 / 200 = 2.5 * x

很好,你的转换是

x ----> 2.5 * (x + 100) 

对于 y 也是如此:

y ----> 2.5 * (y + 100).

希望这说明清楚,并且您将能够在更复杂的情况下重用逻辑。

【讨论】:

  • 好的,谢谢。不知道为什么我如此挣​​扎。让我作为一名数学未成年人感到尴尬:-X 猜我只是在放屁
  • @user1028885:不客气。我有数学学位,我整天在工作中做数学,我确实需要纸和铅笔来做这些事情。很容易把事情搞砸。
  • 典型的数学家!你们这些数字很糟糕。真正的物理学家。 (PS:你知道这是真的!;-)
【解决方案4】:

执行此操作的巧妙而通用的方法是使用仿射变换。 您将有一个 2 x 2 矩阵(称为 A)来表征原始字段对第二个字段的“伸展性”,以及一个 2 x 1 矩阵(称为 b)来表征偏移量。

然后,将 x 作为 (2 x 1) 输入,将 y 作为 (2 x 1) 输出,就是 y = Ax + b。

该技术还可以让您做更多事情(如旋转),但这些可能对您的应用程序并不重要。

http://en.wikipedia.org/wiki/Affine_transformation

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多