将一个三角形变换为另一个三角形

发布于 2024-07-26 22:28:35 字数 1324 浏览 11 评论 0原文

您好,我正在尝试创建仿射变换,它允许我将一个三角形变换为另一个三角形。 我所拥有的是两个三角形的坐标。 你能帮助我吗?

根据 Adam Rosenfield 的回答,我想出了这段代码,以防有人无聊自己解方程:

public static AffineTransform createTransform(ThreePointSystem source,
            ThreePointSystem dest) {        
    double x11 = source.point1.getX();
    double x12 = source.point1.getY();
    double x21 = source.point2.getX();
    double x22 = source.point2.getY();
    double x31 = source.point3.getX();
    double x32 = source.point3.getY();
    double y11 = dest.point1.getX();
    double y12 = dest.point1.getY();
    double y21 = dest.point2.getX();
    double y22 = dest.point2.getY();
    double y31 = dest.point3.getX();
    double y32 = dest.point3.getY();

    double a1 = ((y11-y21)*(x12-x32)-(y11-y31)*(x12-x22))/
                ((x11-x21)*(x12-x32)-(x11-x31)*(x12-x22));
    double a2 = ((y11-y21)*(x11-x31)-(y11-y31)*(x11-x21))/
                ((x12-x22)*(x11-x31)-(x12-x32)*(x11-x21));
    double a3 = y11-a1*x11-a2*x12;
    double a4 = ((y12-y22)*(x12-x32)-(y12-y32)*(x12-x22))/
                ((x11-x21)*(x12-x32)-(x11-x31)*(x12-x22));
    double a5 = ((y12-y22)*(x11-x31)-(y12-y32)*(x11-x21))/
                ((x12-x22)*(x11-x31)-(x12-x32)*(x11-x21));
    double a6 = y12-a4*x11-a5*x12;
    return new AffineTransform(a1, a4, a2, a5, a3, a6);
}

Hi i am trying to create the affine transform that will allow me to transform a triangle into another one. What i have are the coordinates for the 2 triangles. Can you help me?

Following the answer by Adam Rosenfield i came up with this code in case anyone is bored to solve the equation himself :

public static AffineTransform createTransform(ThreePointSystem source,
            ThreePointSystem dest) {        
    double x11 = source.point1.getX();
    double x12 = source.point1.getY();
    double x21 = source.point2.getX();
    double x22 = source.point2.getY();
    double x31 = source.point3.getX();
    double x32 = source.point3.getY();
    double y11 = dest.point1.getX();
    double y12 = dest.point1.getY();
    double y21 = dest.point2.getX();
    double y22 = dest.point2.getY();
    double y31 = dest.point3.getX();
    double y32 = dest.point3.getY();

    double a1 = ((y11-y21)*(x12-x32)-(y11-y31)*(x12-x22))/
                ((x11-x21)*(x12-x32)-(x11-x31)*(x12-x22));
    double a2 = ((y11-y21)*(x11-x31)-(y11-y31)*(x11-x21))/
                ((x12-x22)*(x11-x31)-(x12-x32)*(x11-x21));
    double a3 = y11-a1*x11-a2*x12;
    double a4 = ((y12-y22)*(x12-x32)-(y12-y32)*(x12-x22))/
                ((x11-x21)*(x12-x32)-(x11-x31)*(x12-x22));
    double a5 = ((y12-y22)*(x11-x31)-(y12-y32)*(x11-x21))/
                ((x12-x22)*(x11-x31)-(x12-x32)*(x11-x21));
    double a6 = y12-a4*x11-a5*x12;
    return new AffineTransform(a1, a4, a2, a5, a3, a6);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

一直在等你来 2024-08-02 22:28:35

我假设你在这里谈论的是 2D。 仿射变换矩阵有 9 个值:

    | a1 a2 a3 |
A = | a4 a5 a6 |
    | a7 a8 a9 |

有 3 个输入顶点 x1x2x3,变换后应变为 y1y2y3。 然而,由于我们使用的是齐次坐标,因此将 A 应用于 x1 并不一定会得到 y1 —— 它会给出 y1 的倍数代码>y1。 因此,我们还有未知的乘数 k1k2k3,其方程为:

A*x1 = k1*y1
A*x2 = k2*y2
A*x3 = k3*y3

其中每一个都是一个向量,所以我们真的有 9 个方程有 12 个未知数,因此解将受到约束。 如果我们要求 a7=0a8=0a9=1,那么解决方案将是唯一的(这种选择是自然的,因为这意味着如果输入点是 (x, y, 1),那么输出点将始终具有齐次坐标 1,因此生成的变换只是 2x2 变换加上翻译)。

因此,这将方程简化为:

a1*x11 + a2*x12 + a3 = k1*y11
a4*x11 + a5*x12 + a6 = k1*y12
                   1 = k1
a1*x21 + a2*x22 + a3 = k2*y21
a4*x21 + a5*x22 + a6 = k2*y22
                   1 = k2
a1*x31 + a2*x32 + a3 = k3*y31
a4*x31 + a5*x32 + a6 = k3*y32
                   1 = k3

因此,k1 = k2 = k3 = 1。将这些代入并转换为矩阵形式,得出

| x11 x12   1   0   0   0 |   | a1 |   | y11 |
| x21 x22   1   0   0   0 |   | a2 |   | y21 |
| x31 x32   1   0   0   0 | * | a3 | = | y31 |
|   0   0   0 x11 x12   1 |   | a4 |   | y12 |
|   0   0   0 x21 x22   1 |   | a5 |   | y22 |
|   0   0   0 x31 x32   1 |   | a6 |   | y32 |

:这个 6x6 方程组将为您生成仿射变换矩阵 A。 当且仅当源三角形的 3 个点不共线时,它才会有唯一的解决方案。

I'm going to assume you're talking about 2D here. An affine transformation matrix has 9 values in it:

    | a1 a2 a3 |
A = | a4 a5 a6 |
    | a7 a8 a9 |

There are 3 input vertices x1, x2, and x3, which when transformed should become y1, y2, y3. However, since we're working in homogeneous coordinates, applying A to x1 doesn't necessarily give y1 -- it gives a multiple of y1. So, we also have the unknown multipliers k1, k2, and k3, with the equations:

A*x1 = k1*y1
A*x2 = k2*y2
A*x3 = k3*y3

Each of those is a vector, so we really have 9 equations in 12 unknowns, so the solution is going to be underconstrained. If we require that a7=0, a8=0, and a9=1, then the solution will be unique (this choice is natural, since it means if the input point is (x, y, 1), then the output point will always have homogeneous coordinate 1, so the resulting transform is just a 2x2 transform plus a translation).

Hence, this reduces the equations to:

a1*x11 + a2*x12 + a3 = k1*y11
a4*x11 + a5*x12 + a6 = k1*y12
                   1 = k1
a1*x21 + a2*x22 + a3 = k2*y21
a4*x21 + a5*x22 + a6 = k2*y22
                   1 = k2
a1*x31 + a2*x32 + a3 = k3*y31
a4*x31 + a5*x32 + a6 = k3*y32
                   1 = k3

So, k1 = k2 = k3 = 1. Plugging these in and converting to matrix form yields:

| x11 x12   1   0   0   0 |   | a1 |   | y11 |
| x21 x22   1   0   0   0 |   | a2 |   | y21 |
| x31 x32   1   0   0   0 | * | a3 | = | y31 |
|   0   0   0 x11 x12   1 |   | a4 |   | y12 |
|   0   0   0 x21 x22   1 |   | a5 |   | y22 |
|   0   0   0 x31 x32   1 |   | a6 |   | y32 |

Solving this 6x6 system of equations yields you your affine transformation matrix A. It will have a unique solution if and only if the 3 points of your source triangle are not collinear.

执笏见 2024-08-02 22:28:35

嘿,伙计们,不失一般性,让两个三角形以原点作为一个顶点(稍后可以添加仿射移位),这样它们就由点 0、a、b、c、d 定义 然后将你的点 x 乘以矩阵 NM

,其中

M = inverse(a b) <--- 这是带有点 a 的 2x2 矩阵b 作为其列

,并且

N = (c d)

应该可以。

Hey, guys, Without Loss of Generality, make the two triangles have the origin as one vertex (you can tack on the affine shift later), so they're defined by the points 0, a, b, c, d then multiply your points x by the matrix NM

where

M = inverse(a b) <--- this is 2x2 matrix with the points a and b as its columns

and

N = (c d)

That should do it.

盛夏已如深秋| 2024-08-02 22:28:35

如果我理解正确的话,你的三角形具有相同的大小和角度,所以你应该能够对它们进行变换,使它们(至少)有一个共同点。 此后,它们应该仅在旋转方面有所不同或者可以进行镜像,因此您可以获取三角形线之间的角度并尝试使用这些角度进行旋转,如果没有一个角度起作用,则可以镜像其中一个三角形。

编辑:好的,这还不够,仿射变换还可以包含剪切和缩放...缩放可以很容易完成,只需除以线的长度,这也会为您提供有关三角形相应线的一些信息,但是剪切会更难......

OTOH,你不能为此解决一些方程组吗? 毕竟,应该有一个变换矩阵和3个点(新的和旧的)......

If I understand this correctly, your triangles have the same size and angles, so you should be able to tranform them so that they have (at least) one point in common. After this, they should only differ in rotation or could be mirrored, so you could f.e. get the angles between the triangle lines and try these for rotation and could mirror one of the triangles if none of the angles works.

EDIT: OK, that's not enough, affine transformations also can contain shear and scaling... Scaling could be done easily, just divide the length of the lines, this will also give you some information about corresponding lines of the triangles, but shearing will be harder...

OTOH, couldn't you just solve some equation system for this? After all, there should be a transformation matrix and 3 points (new and old)...

亣腦蒛氧 2024-08-02 22:28:35

只需将问题表述为一组方程,然后求解即可:

P1 * M = P1'
P2 * M = P2'
P3 * M = P3'

M 是一个 3x3 矩阵,例如:

[m00, m01, m02;
 m10, m11, m12;
 0  ,   0,   1]

P_i 是一个元组 [k*x_i, k* y_i, k](齐次坐标)...

您现在可以尝试展开上面显示的 3 个矩阵方程并创建一个新系统,将 m_ij 作为隐喻并求解它,但是如果我没有遗漏某些东西(也许我遗漏了),那么您需要多一点来完全指定转换,否则您将拥有额外的自由度(当然您可以修复它)。

Just formule the problem as a set of equations and then solve it:

P1 * M = P1'
P2 * M = P2'
P3 * M = P3'

M is a 3x3 matrix like:

[m00, m01, m02;
 m10, m11, m12;
 0  ,   0,   1]

And P_i is a tuple [k*x_i, k*y_i, k] (homogeneous coordinates)...

You can now try to expand the 3 matricial equations shown above and make a new system, with the m_ij as incognits and solve it, but if I'm not missing something (and maybe I am), you need one point more to specify completely the transformation, or otherwise you'll have an extra degree of freedom (and of course you can fix it).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文