algorithm - 从哪里获得用于将 RGB 平行四边形投影到 RGB 三角形的伪代码算法

标签 algorithm geometry pseudocode projection

将平行四边形((RGB)点的二维数组)投影到三角形((RGB)点的二维数组)(在我的特定情况下,将矩形投影到具有相同边长的直角三角形)的伪代码算法是什么(等腰),在我的例子中,斜边的大小与矩形的最大边相同)质量可能会丢失。那么如何在伪代码中执行这样的操作呢?

所以通常我们有例如 300x200

alt text

我们想把它扭曲成 150 高和 200 宽的三角形

烟花 CS5 - 对我来说不是正确的结果

alt text

使用 photoshop CS5 正确结果

alt text

所以我想知道 photoshop 进行转换的伪代码是什么?

最佳答案

我不确定我是否误解了您的问题,但这是我的想法。我假设投影将使得三角形的斜边与矩形的最长边的方向相同,因为你说它们的大小相同。一些粗略的图片(不按​​比例):

矩形 H=4,W=10

---------
|       |
|       |
---------

三角形 Hyp=10,S1=8,S2=6

      .
   .   |
.      |
--------

所以我的建议是进行映射,使矩形的“ block ”等同于带有三角形的点,并且每个三角形点是相关矩形 block 的 RGB 平均值,注意 block 可能会重叠,具体取决于原始对象的比例。

更具体一点,回到上面的例子,首先是比率,高度比率是固定的,矩形是4高,三角形是6高,所以对于三角形垂直方向的每个像素考虑6/4,或者1.5矩形。现在有两个选项来处理“.5”,您可以考虑向上或向下舍入并仅使用整 block ,或者您可以对小数部分使用权重。由于后一种情况不那么微不足道,我们将进一步研究它。

当我们垂直移动时,任何小数部分都将转换为该行像素的小数权重,因此如果我们垂直平均并且我们的像素为 128 和 137(为简单起见仅查看一个分量),那么我们的平均值将是

(128+(0.5*137))/1.5 = (128+68.5)/1.5 = 196.5/1.5 = 131

现在,由于我们正在查看小数部分,因此我们需要跟踪我们未使用的小数部分,因此如果上面的下一个像素是 100,我们将要查看

((137*0.5)+100)/1.5 = (68.5+100)/1.5 = 168.5/1.5 = 112.3

现在我们遵循类似的策略,逐行垂直向上移动三角形,随着三角形宽度的减小调整比率,因此对于 hypotenuse=rectangle 的底边,这通常是 1。再往上你可能会有这样的比率为 1.23,可以进行上述计算。

最后是一些粗略的伪代码:

map(rectangle, triangle) {

  decimal yRatio = triangle.height / rectangle.height
  decimal lastY = 0;//we need decimal indeices for fractional averages

  for each line in dest height (yIndex, 0 based) {
    //here you could even find the average width of the rectangle
    //over the block height, but we won't bother
    decimal xRatio = triangle[yIndex].width / rectangle[floor(yIndex*yRatio)].width
    decimal lastX = 0;    //again a decimal for fractional averages

    for each pixel in dest line width (xIndex, 0 based) {

        decimal pixelAverage = 0;
        decimal tempYRatio = yRatio;
        decimal destY = yRatio * yIndex;

        //Here we calculate the source pixel block average
        while(tempYRatio > 0) {
          //the portion of this row of pixels we use is the minimum
          //of the distance to the next integer, and what we need
          decimal yFraction = minimum(tempYRatio, nextInt(destY) - destY);

          decimal tempXRatio = xRatio;
          decimal destX = xRatio * xIndex;
          while(tempXRatio > 0) {
            decimal xFraction = minimum(tempXRatio, nextInt(destX) - destX);
            //now add the weighted pixel to the average
            average += rectangle[floor(destY)][floor(destX)]*xFraction*yFraction;

            tempXRatio -= xFraction;  //reduce the block size
            destX += xFraction;       //and shift the source index
          }

          tempYRatio -= yFraction;  //reduce the block size
          destY += yFraction;       //and shift the source index
        }

        destination[yIndex][xIndex] = average / (xRatio*yRatio);
    }
  }
}
//a helper function to find the next integer value
integer nextInt(decimal d) {
  integer ret = ceiling(d);
  return d == ret ? d+1 : ret;
}

这超出了我的想象,所以我不能保证它是完全正确的,但它至少应该是一个好的开始,对各个像素的每个 RGB 分量执行适当的平均。

关于algorithm - 从哪里获得用于将 RGB 平行四边形投影到 RGB 三角形的伪代码算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4632449/

相关文章:

algorithm - 没有比赛顺序的 Elo 评分系统

c++ - absl::flat_hash_map:实现 `remove_if` 的有效方法

algorithm - 什么是找到重叠矩形区域的有效算法

algorithm - 寻找哈希算法的伪代码(开放、链接和多重)

python - 在垃圾箱之间平均分配一个数字

algorithm - 如何处理域类中的依赖行为?

algorithm - 确定平均弧线

3d - Curve Fitting 3D 数据集

algorithm - 遍历边缘和解决交叉点的优雅而有效的方法

java - Zip - 添加较新的文件和文件夹,删除旧的文件和文件夹