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

3
我正在编写一个函数,在Windows Forms应用程序的客户区中绘制UI手柄(旋转、调整大小等)。当选择对象时,该函数被调用。
调用者向我发送一个正确旋转、缩放和平移的Graphics对象,以适应更大的事物方案(选定对象具有自己的旋转/平移/缩放,UI手柄相对于选定对象具有相对平移和旋转)。现在,我希望我的UI手柄在父级(选定对象)的任何缩放比例下都是相同的大小。
如何在变换矩阵中消除/重置缩放因子?如何重置为1的缩放比例同时保留宝贵的平移和旋转值?
2个回答

1

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

  1. 计算变换的旋转
  2. 复制变换并应用相反的旋转
  3. 变换两个已知点并从结果计算比例

翻译成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 代码还包含一个警告,即存在退化情况,这种情况下可能无法正确工作,但对于您的情况可能会有用。

好主意。但似乎有点贵。 - Agnel Kurian

1

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

也许只需记录迄今为止应用的比例(我们称之为currentscale),并将1/currentscale的比例添加到您的变换中。


暂时接受。这正是我一直怀疑的。有没有办法从变换矩阵中检索缩放组件?我尝试过,但它会影响旋转。 - Agnel Kurian
不,至少我目前不知道有通用方法。如果只进行了简单的比例尺操作,那么这很容易解决,但是如果矩阵执行更复杂的操作,则问题就不再那么简单了。 - Lucero

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接