【问题标题】:Return CATransform3D to map quadrilateral to quadrilateral返回 CATransform3D 以将四边形映射到四边形
【发布时间】:2012-01-31 23:58:00
【问题描述】:

我正在尝试派生一个 CATransform3D,它将一个具有 4 个角点的四边形映射到另一个具有 4 个新角点的四边形。我花了一点时间研究这个,似乎这些步骤涉及将原来的 Quad 转换为 Square,然后将该 Square 转换为新的 Quad。我的方法是这样的(代码借自here):

- (CATransform3D)quadFromSquare_x0:(float)x0 y0:(float)y0 x1:(float)x1 y1:(float)y1 x2:(float)x2 y2:(float)y2 x3:(float)x3 y3:(float)y3 {

    float dx1 = x1 - x2,    dy1 = y1 - y2;
    float dx2 = x3 - x2,    dy2 = y3 - y2;
    float sx = x0 - x1 + x2 - x3;
    float sy = y0 - y1 + y2 - y3;
    float g = (sx * dy2 - dx2 * sy) / (dx1 * dy2 - dx2 * dy1);
    float h = (dx1 * sy - sx * dy1) / (dx1 * dy2 - dx2 * dy1);
    float a = x1 - x0 + g * x1;
    float b = x3 - x0 + h * x3;
    float c = x0;
    float d = y1 - y0 + g * y1;
    float e = y3 - y0 + h * y3;
    float f = y0;

    CATransform3D mat;

    mat.m11 = a;
    mat.m12 = b;
    mat.m13 = 0;
    mat.m14 = c;

    mat.m21 = d;
    mat.m22 = e;
    mat.m23 = 0;
    mat.m24 = f;

    mat.m31 = 0;
    mat.m32 = 0;
    mat.m33 = 1;
    mat.m34 = 0;

    mat.m41 = g;
    mat.m42 = h;
    mat.m43 = 0;
    mat.m44 = 1;

    return mat;

}

- (CATransform3D)squareFromQuad_x0:(float)x0 y0:(float)y0 x1:(float)x1 y1:(float)y1 x2:(float)x2 y2:(float)y2 x3:(float)x3 y3:(float)y3 {

    CATransform3D mat = [self quadFromSquare_x0:x0 y0:y0 x1:x1 y1:y1 x2:x2 y2:y2 x3:x3 y3:y3];

    // invert through adjoint

    float a = mat.m11,      d = mat.m21,    /* ignore */            g = mat.m41;
    float b = mat.m12,      e = mat.m22,    /* 3rd col*/            h = mat.m42;
    /* ignore 3rd row */
    float c = mat.m14,      f = mat.m24;

    float A =     e - f * h;
    float B = c * h - b;
    float C = b * f - c * e;
    float D = f * g - d;
    float E =     a - c * g;
    float F = c * d - a * f;
    float G = d * h - e * g;
    float H = b * g - a * h;
    float I = a * e - b * d;

    // Probably unnecessary since 'I' is also scaled by the determinant,
    //   and 'I' scales the homogeneous coordinate, which, in turn,
    //   scales the X,Y coordinates.
    // Determinant  =   a * (e - f * h) + b * (f * g - d) + c * (d * h - e * g);
    float idet = 1.0f / (a * A           + b * D           + c * G);

    mat.m11 = A * idet;     mat.m21 = D * idet;     mat.m31 = 0;    mat.m41 = G * idet;
    mat.m12 = B * idet;     mat.m22 = E * idet;     mat.m32 = 0;    mat.m42 = H * idet;
    mat.m13 = 0       ;     mat.m23 = 0       ;     mat.m33 = 1;    mat.m43 = 0       ;
    mat.m14 = C * idet;     mat.m24 = F * idet;     mat.m34 = 0;    mat.m44 = I * idet;

    return mat;

}

在计算两个矩阵、将它们相乘并分配给相关视图之后,我最终得到了一个转换后的视图,但它非常不正确。事实上,无论我做什么,它似乎都像平行四边形一样被剪切。我错过了什么?

2/1/12 更新

似乎我遇到问题的原因可能是我需要将 FOV 和焦距适应模型视图矩阵(这是我可以直接在 Quartz 中更改的唯一矩阵。)我没有任何不过,很幸运可以在线找到有关如何计算正确矩阵的文档。

【问题讨论】:

  • 更新:我现在尝试移植一些算法,每次都得到一个平行四边形。一定有什么我忘记了,但我不知所措。
  • 这是实现此目的的另一种方法:stackoverflow.com/questions/9470493/… 如果这有帮助,请告诉我。

标签: objective-c ios graphics 3d linear-algebra


【解决方案1】:

我能够通过从这两个 URL 移植和组合四边形变形和单应性代码来实现这一点:

更新:我已经开源了一个这样做的小类:https://github.com/dominikhofmann/DHWarpView

【讨论】:

  • 您好,您能否提供更多关于您移植和组合的代码的信息?我目前正在尝试解决与您完全相同的问题,但我无处可去。谢谢!
  • 欢迎来到 Stack Overflow!虽然这在理论上可以回答这个问题,it would be preferable 在此处包含答案的基本部分,并提供链接以供参考。
  • 感谢您的反馈。我已经开源了我写的类来完成这个
猜你喜欢
  • 1970-01-01
  • 2017-04-29
  • 2019-02-27
  • 2012-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多