在GDI +转换矩阵中重置比例

时间:2009-05-11 07:00:42

标签: .net winforms gdi+ transform scaling

我正在编写一个函数来在Windows窗体应用程序的客户区域中绘制UI句柄(旋转,调整大小等)。选择对象时会调用该函数。

调用者向我发送一个正确旋转,缩放和翻译的Graphics对象以适应更大的事物方案(所选对象具有自己的旋转/平移/缩放,并且UI句柄具有与所选对象相对的平移和旋转)。现在,无论父级(选定对象)的规模如何,我都希望我的UI句柄大小相同。

如何在转换矩阵中消除/重置比例因子?如何在保留珍贵的平移和旋转值的同时重置为1?

2 个答案:

答案 0 :(得分:1)

您必须意识到转换的顺序很重要。因此,仅删除比例可能会更改以下翻译的“含义”(例如偏移)。

也许只保留到目前为止应用的比例记录(让我们称之为currentscale)并在转换中添加1/currentscale比例。

答案 1 :(得分:1)

Anti-Grain Geometry使用基本方法确定转换的缩放(在agg_trans_affine.cpp中找到的实现)。它通过以下方式实现:

  1. 计算转换的轮换
  2. 复制转换并应用反向旋转
  3. 转换两个已知点并根据结果计算比例
  4. 转换为C#,看起来像:

    Matrix transform = (Matrix)graphics.Transform.Clone();
    
    PointF[] rotationPoints = new PointF[] { new PointF(0, 0), new PointF(1, 0) };
    transform.TransformPoints(rotationPoints);
    
    double rotationRadians = Math.Atan2(rotationPoints[1].Y - rotationPoints[0].Y, rotationPoints[1].X - rotationPoints[0].X);
    transform.Rotate((float)(-rotationRadians * (180.0 / Math.PI)));
    
    PointF[] scalePoints = new PointF[] { new PointF(0, 0), new PointF(1, 1) };
    transform.TransformPoints(scalePoints);
    
    float xScale = scalePoints[1].X - scalePoints[0].X;
    float yScale = scalePoints[1].Y - scalePoints[0].Y;
    

    AGG代码还包含一个警告,指出存在无法正常工作的退化情况,但它可能对您的情况有用。