You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Direct2D变换组合问题:旋转与翻转锚点适配异常排查

Direct2D中旋转与翻转组合的变换矩阵问题

我使用C++和Direct2D开发,需要一个能整合所有变换的函数,重点解决旋转与翻转的组合冲突问题。目前单独围绕锚点旋转或翻转对象均能正常工作,但同时应用这两个变换时,翻转方向不符合预期,且锚点会出现偏移。我将翻转、旋转、缩放、平移属性分开存储,绘制时合并为单个变换矩阵,锚点可选 bounding rectangle 的9个点位之一,但组合操作时锚点或最终平移总是出现错误,以下是我生成变换矩阵的函数代码:

D2D1_MATRIX_3X2_F ImageChanges::GetTransformMatrix()
{
    D2D1_SIZE_F                 szBounds;
    D2D1_SIZE_F                 szFlipSigns;
    D2D1_POINT_2F               ptPrevAnchor;
    D2D1_POINT_2F               ptAnchor;
    D2D1_RECT_F                 rBounds;
    D2D1_MATRIX_3X2_F           mxRotation;
    D2D1_MATRIX_3X2_F           mxFlip;
    D2D1_MATRIX_3X2_F           mxScale;
    D2D1_MATRIX_3X2_F           mxOffsetLayer;
    D2D1_MATRIX_3X2_F           mxOffsetOrigin;
    D2D1_MATRIX_3X2_F           mxLayerCentre;
    D2D1_MATRIX_3X2_F           mxAnchorDifference;
    D2D1_SIZE_F                 szAnchorDifference;
    D2D1_MATRIX_3X2_F           mxTransform;

    mxTransform = Matrix3x2F::Identity();

    if(m_bCanvas == false)
    {
        // 获取变换前的锚点
        ptAnchor = m_infoCurrent.ptAnchor;
        

        // 创建旋转矩阵
        mxOffsetOrigin = Matrix3x2F::Translation(-ptAnchor.x, -ptAnchor.y);
        mxLayerCentre  = Matrix3x2F::Translation(ptAnchor.x, ptAnchor.y);
        mxRotation     = mxOffsetOrigin * Matrix3x2F::Rotation(m_infoCurrent.flAngle) * mxLayerCentre;


        // 将图层移回原点
        mxOffsetOrigin = Matrix3x2F::Translation(-ptAnchor.x, -ptAnchor.y);


        // 保存旋转前的锚点
        ptPrevAnchor = ptAnchor;
        

        // 计算旋转后的锚点位置
        szBounds = GetCurrentSize();
        rBounds  = {0.0f, 0.0f, szBounds.width, szBounds.height};

        Matrix3x2F          mxoAnchor;
        mxoAnchor = *Matrix3x2F::ReinterpretBaseType(&Matrix3x2F::Rotation(m_infoCurrent.flAngle));
        ptAnchor = mxoAnchor.TransformPoint(ptAnchor);

        ptAnchor = {(float)abs(ptAnchor.x), (float)abs(ptAnchor.y)};
        

        // 创建变换后锚点的平移矩阵
        szAnchorDifference = {ptPrevAnchor.x - ptAnchor.x, ptPrevAnchor.y - ptAnchor.y};
        mxAnchorDifference = Matrix3x2F::Translation(szAnchorDifference);

        
        // 创建缩放与翻转矩阵
        szFlipSigns.width  = (m_infoCurrent.nFlip & DKL_GOP_FLIP_HORIZONTAL) == DKL_GOP_FLIP_HORIZONTAL? -1.0f: 1.0f;
        szFlipSigns.height = (m_infoCurrent.nFlip & DKL_GOP_FLIP_VERTICAL)   == DKL_GOP_FLIP_VERTICAL?   -1.0f: 1.0f;

        mxOffsetOrigin = Matrix3x2F::Translation(-ptAnchor.x, -ptAnchor.y);
        mxFlip         = Matrix3x2F::Scale(szFlipSigns);
        mxScale        = Matrix3x2F::Scale(m_infoCurrent.szScale);
        mxLayerCentre  = Matrix3x2F::Translation(ptAnchor.x, ptAnchor.y);

        mxScale = mxOffsetOrigin * mxFlip * mxScale * mxLayerCentre;


        // 创建对象的平移矩阵
        mxOffsetLayer = Matrix3x2F::Translation(m_infoCurrent.ptOffset.x, m_infoCurrent.ptOffset.y);


        // 创建最终变换矩阵
        mxTransform = mxRotation * mxScale * mxOffsetLayer * mxAnchorDifference;
    }

    return mxTransform;
}

内容的提问来源于stack exchange,提问作者davecupper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.03 04:04:49