您好我正在尝试创建仿射变换,这将允许我将三角形转换为另一个三角形。我所拥有的是2个三角形的坐标。你能救我吗?
按照亚当罗森菲尔德的回答,我提出了这个代码,万一有人无聊自己解决这个问题:
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);
}
答案 0 :(得分:13)
我假设你在这里谈论2D。仿射变换矩阵中有9个值:
| a1 a2 a3 | A = | a4 a5 a6 | | a7 a8 a9 |
有3个输入顶点x1
,x2
和x3
,它们在转换后应变为y1
,y2
,y3
。但是,由于我们在齐次坐标系中工作,因此将A
应用于x1
并不一定会给y1
- 它会给出y1
的倍数。因此,我们还有未知的乘数k1
,k2
和k3
,其中包含以下公式:
A*x1 = k1*y1 A*x2 = k2*y2 A*x3 = k3*y3
每个都是一个向量,所以我们确实有12个未知数的9个方程,因此解决方案将受到不足。如果我们需要a7=0
,a8=0
和a9=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个点不共线时,它将具有唯一的解决方案。
答案 1 :(得分:2)
,其中
M =逆( ab )< ---这是2x2矩阵,其中 a 和 b 为其列
和
N =( c d )
应该这样做。
答案 2 :(得分:1)
如果我理解正确,你的三角形具有相同的大小和角度,所以你应该能够转换它们,使它们(至少)有一个共同点。在此之后,它们应该只有不同的旋转或镜像,所以你可以f.e.获取三角形线之间的角度并尝试这些角度进行旋转,如果没有角度可以工作,则可以镜像其中一个三角形。
编辑:好的,这还不够,仿射变换也可以包含剪切和缩放......缩放可以很容易地完成,只需要划分行的长度,这也会给你一些关于三角形相应行的信息,但剪毛会更难...... OTOH,你难道不能为此解决一些方程式系统吗?毕竟,应该有一个转换矩阵和3个点(新旧)......答案 3 :(得分:1)
将问题形成一组方程式,然后解决它:
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个matricial方程并创建一个新的系统,m_ij
作为不可知并解决它,但是如果我没有遗漏某些东西(也许我是),你需要更多一点来完全指定转换,否则你将获得额外的自由度(当然你可以修复它)。