美文网首页
坐标映射算法

坐标映射算法

作者: NullUser | 来源:发表于2023-04-24 13:42 被阅读0次

矩形根据某点进行缩放并以该点为中心

    /**
     * Scale the rectangle around its center point.
     */
    void scale( double scaleFactor, const QgsPointXY *c = nullptr )
    {
      // scale from the center
      double centerX, centerY;
      if ( c )
      {
        centerX = c->x();
        centerY = c->y();
      }
      else
      {
        centerX = mXmin + width() / 2;
        centerY = mYmin + height() / 2;
      }
      scale( scaleFactor, centerX, centerY );
    }

    /**
     * Scale the rectangle around its center point.
     */
    void scale( double scaleFactor, double centerX, double centerY )
    {
      const double newWidth = width() * scaleFactor;
      const double newHeight = height() * scaleFactor;
      mXmin = centerX - newWidth / 2.0;
      mXmax = centerX + newWidth / 2.0;
      mYmin = centerY - newHeight / 2.0;
      mYmax = centerY + newHeight / 2.0;
    }

将矩形a完整放入矩形b,计算此时矩形a坐标映射到矩形b坐标的转换矩阵。

目前矩形b的minx和miny需要是0。
实现以下效果:A和B是任意矩形,将A通过等比例缩放后,完全放入B,计算此时从A坐标到B坐标的转换矩阵。

image.png

参考:


image.png
struct Rect 
{
    double minx;
    double maxx;
    double miny;
    double maxy;
};
/**
 * @brief 将矩形a完整放入矩形b,计算此时矩形a坐标映射到矩形b坐标的转换矩阵
 */
QMatrix calculateMatrix(Rect& a, Rect b)
{
    QMatrix matrix;


    double aWidth = a.maxx - a.minx;
    double aHeight = a.maxy - a.miny;
    //计算矩形a宽高比
    double aWHRatio = aWidth / aHeight;

    double bWidth = b.maxx - b.minx;
    double bHeight = b.maxy - b.miny;
    //计算矩形b宽高比
    double bWHRatio = bWidth / bHeight;

    //1.计算a到b的缩放,计算b/a
    double scale = 1;
    if (bWHRatio >= aWHRatio)
    {
        scale = bHeight / aHeight;
    }
    else
    {
        scale = bWidth / aWidth;
    }

    //2.计算偏移量,使a位于b的中心位置
    double aMidX = (a.maxx + a.minx) / 2;
    double bMidX = (b.maxx + b.minx) / 2;
    double xOffsetAfterScaled = (bMidX - aMidX * scale);

    double aMidY = (a.maxy + a.miny) / 2;
    double bMidY = (b.maxy + b.miny) / 2;
    double yOffsetAfterScaled = (bMidY - aMidY * scale);

    matrix.scale(scale, scale);
    matrix.translate(xOffsetAfterScaled / scale, yOffsetAfterScaled / scale);

    return matrix;
};

以矩形上某一点为锚点,缩放后,新矩形相对位置上仍为原坐标。

实现以下效果:将黄色矩形以其上某点(如:90,90)进行放大2倍后,获得新矩形绿色。


image.png
Rect scaleByPos(Rect rect, double scaleFactor, Point pos)
{
    Rect scaledRect;
    //假设窗口
    Rect window = rect;

    //窗口映射到矩形的转换矩阵
    QMatrix windowMatrix = calculateMatrix(window, rect);
    double originX, originY;
    windowMatrix.map(pos.x, pos.y, &originX, &originY);

    //原始中心点坐标
    double originCenterX, originCenterY;
    originCenterX = (rect.minx + rect.maxx) / 2;
    originCenterY = (rect.miny + rect.maxy) / 2;

    //计算缩放后的矩形宽高
    double newWidth = (rect.maxx - rect.minx) * scaleFactor;
    double newHeight = (rect.maxy - rect.miny) * scaleFactor;

    //计算以中心点进行缩放后的矩形
    Rect originCenterScaledRect = {
        originCenterX - newWidth / 2,
        originCenterX + newWidth / 2,
        originCenterY - newHeight / 2,
        originCenterY + newHeight / 2
    };

    //将新矩形放入窗口
    QMatrix tempMatrix = calculateMatrix(originCenterScaledRect, window);
    //获取窗口到新矩形的转换矩阵
    QMatrix matrix = tempMatrix.inverted();

    //计算锚点在新矩形中的坐标
    //即原始矩形坐标pos,放入新矩形originCenterScaledRect后的坐标
    double newX, newY;
    matrix.map(pos.x, pos.y, &newX, &newY);

    //计算偏移
    double centerX = originCenterX - (newX - originX);
    double centerY = originCenterY - (newY - originY);

    scaledRect = {
        centerX - newWidth / 2,
        centerX + newWidth / 2,
        centerY - newHeight / 2,
        centerY + newHeight / 2
    };

    return scaledRect;

};

相关文章

  • OpenGL ES 分屏滤镜

    分屏滤镜的实现(分屏算法):主要渲染区域与纹理坐标映射对应关系。解析案例中2、3、4、6、9分屏中纹理坐标与渲染区...

  • 《计算机组成与体系结构》——4.2cache的映射

    1 映射算法 由于cache的行比主存的块要少,因此需要一种算法来实现主存到cache行的映射。通常采用三种映射方...

  • 2. 环形布局(Circular layout)

    2.1 坐标转换(Coordinate transformation) 为了将图形映射到圆中,需要进行多个坐标系的...

  • 动画

    Matrix 作用就是坐标映射,转成实际的坐标位置。基本变换有4种: 平移(translate)、缩放(scale...

  • 哈希算法

    哈希算法 将任意长度的二进制值映射为固定长度的二进制值串,这个映射的规则就是“哈希算法”,而通过原始数据映射之后得...

  • 相机标定知识和深度数据映射彩色数据

    旋转矩阵坐标系转换一坐标系转换二Kinect 深度转彩色公式推导刚体变换Kinect1代正确映射映射详解用自己的k...

  • 哈希算法

    什么是哈希算法 将任意长度的二进制值串映射为固定长度的二进制值串,这个映射的规则就是哈希算法,通过原始数据映射之后...

  • 第二十一节-哈希算法(上)

    什么是哈希算法 将任意长度的二进制值串映射成固定长度的二进制值串,这个映射规则就是哈希算法,而通过原始数据映射之后...

  • 哈希算法

    什么是哈希算法? 将任意长度的二进制值串映射为固定长度的二进制值串,这个映射的规则就是哈希算法,而通过原始数据映射...

  • 哈希算法

    什么是哈希算法? 将任意长度的二进制值串映射为固定长度的二进制值串,这个映射的规则就是哈希算法,而通过原始数据映射...

网友评论

      本文标题:坐标映射算法

      本文链接:https://www.haomeiwen.com/subject/fzuujdtx.html