Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何计算包含旋转图像(可能包含透明像素)的矩形的大小_C_Geometry_Rotation_Rectangles_Cairo - Fatal编程技术网

C 如何计算包含旋转图像(可能包含透明像素)的矩形的大小

C 如何计算包含旋转图像(可能包含透明像素)的矩形的大小,c,geometry,rotation,rectangles,cairo,C,Geometry,Rotation,Rectangles,Cairo,给定旋转图像的θ弧度角、宽度和高度,如何计算包含旋转图像的外部矩形的新宽度和高度 换句话说,我如何计算新的粘接盒宽度/高度? 请注意,图像实际上可能是圆形的,边缘上有透明像素 那就是:x1,y1 实际上,我正在使用cairo\u rotate()旋转一个原点位于中心的pixbuf,我需要知道新分配的区域。我尝试的是: double geo_rotated_rectangle_get_width (double a, double b, double theta) { return ab

给定旋转图像的
θ
弧度角、
宽度
高度
,如何计算包含旋转图像的外部矩形的新宽度和高度

换句话说,我如何计算新的粘接盒宽度/高度? 请注意,图像实际上可能是圆形的,边缘上有透明像素

那就是:x1,y1

实际上,我正在使用
cairo\u rotate()
旋转一个原点位于中心的pixbuf,我需要知道新分配的区域。我尝试的是:

double geo_rotated_rectangle_get_width (double a, double b, double theta)
{
    return abs(a*cos(theta)) + abs(b*sin(theta));
}
它的工作原理是总是返回足够的空间来容纳旋转后的图像,但当图像没有以90度的倍数旋转并且是完全不透明的图像(正方形)时,它也总是返回比它应该返回的值更高的值


编辑: 这是我正在旋转的图像:

有趣的是,我刚刚尝试了一张同样大小的完全不透明的图像,结果还可以。我使用
gdk\u pixbuf\u get\u width()
来获取宽度,无论如何,它都返回相同的值。因此,我假设公式是正确的,问题是没有考虑透明度。当以对角线方向旋转时,旋转图像矩形中的边是透明的


我将保留以上内容,以便对其他人有所帮助:)
现在的问题是如何计算边上的透明像素

要确定旋转矩形的bbox,可以计算4个顶点的坐标并取这4个点的bbox

  • a
    是未旋转矩形的宽度,
    b
    是其高度

  • 设diag=sqrt(a*a+b*b)/2此矩形中心到右上角的距离。您可以使用
    diag=hypot(a,b)/2
    以获得更好的精度

  • 首先计算
    theta=0
    的第一条对角线的角度
    theta0
    theta0=atan(b/a)
    或更好的
    theta0=atan2(b,a)

  • 这4个顶点是:

    • {
      diag*cos(θ0+θ)
      diag*sin(θ0+θ)
      }
    • {
      diag*cos(pi-theta0+theta)
      diag*sin(pi-theta0+theta)
      }
    • {
      diag*cos(pi+theta0+theta)
      diag*sin(pi+theta0+theta)
      }
    • {
      diag*cos(-theta0+theta)
      diag*sin(-theta0+theta)
      }
  • 可简化为:

    • {
      diag*cos(θ+θ0)
      diag*sin(θ+θ0)
      }
    • {
      -diag*cos(theta-theta0)
      -diag*sin(theta-theta0)
      }
    • {
      -diag*cos(θ+θ0)
      -diag*sin(θ+θ0)
      }
    • {
      diag*cos(theta-theta0)
      diag*sin(theta-theta0)
      }
  • 给出了
    x1
    y1

    • x1=diag*fmax(fabs(cos(θ+θ0)),fabs(cos(θ-θ0))
    • y1=diag*fmax(fabs(sin(θ+θ0)),fabs(sin(θ-θ0))
  • 旋转矩形的
    宽度
    高度
    如下所示:

    • width=2*diag*fmax(fabs(cos(θ+θ0)),fabs(cos(θ-θ0))
    • height=2*diag*fmax(晶圆(sin(θ+θ0)),晶圆(sin(θ-θ0))
这是几何解决方案,但您必须考虑图形原语执行的舍入,因此最好使用图形API并使用
gdk_pixbuf_get_width()
gdk_pixbuf_get_height()
检索pixbuf尺寸,这将允许精确放置。

“让cairo计算这些坐标”。如果您有权访问
cairo\u t*
,您可以执行以下操作(未经测试!):


上面的代码应用了一些转换,然后构造了一条路径。这使得cairo将转换应用到给定的坐标。之后,转换被
cairo\u restore()丢弃
。接下来,我们向cairo询问当前路径所覆盖的区域,它在当前坐标系中提供了该区域,即未进行转换。

。然后找到x和y的最小值和最大值。我在几何方面真的不是很好,hahaUpvoted,这是一个有用的补充。但是,我担心我的编辑会使我的指定变得松散ic问题,但这没关系。我最初使用的术语是平方,因为这就是PIXBUF的最终含义,但问题的出现是因为一些PIXBUF实际上是复杂的图形,并且具有透明性,并且键合盒应该考虑到它们。我试过了,也很有效(我不得不使用
fabs
)…)如果您认为它是有用的,并且您知道有一种方法可以做到这一点,请添加如何解释图像的边缘,该图像应该不是完全不透明的矩形。@Edenia:确实应该使用
fabs()
,并且
fmax()
太多了。@Edenia:对于部分透明的图像,没有魔弹,你必须分析旋转后的位图来确定实际图像的实际尺寸。例如,问题中的图像似乎靠近一个圆盘,因此鸟头的尺寸不受旋转的影响。这是透明像素的原因吗?No、 它只看矩形的范围,我不认为在cairo中有任何东西可以提供关于透明像素的信息。
double x1, y1, x2, y2;
cairo_save(cr);
cairo_rotate(cr, theta); // You can also do cairo_translate() and whatever your heart desires
cairo_new_path(cr);
cairo_rectangle(cr, x, y, width, height);
cairo_restore(cr); // Note: This preserved the path!
cairo_fill_extents(cr, &x1, &y1, &x2, &y2);
cairo_new_path(cr); // Clean up after ourselves
printf("Rectangle is inside of (%g,%g) to (%g,%g) (size %g,%g)\n",
    x1, y1, x2, y2, x2 - x1, y2 - y1);