2D点,3D,然后返回2D

时间:2013-02-20 09:27:41

标签: objective-c macos core-graphics

图1: 我在2d(CoreGraphics)的一个图层上绘制了一个bezier,我有点A& B.

图2: 我可以将图层旋转大约70度。

图3: 我想知道A& A点是什么B现在以某种方式将图像从3D压缩回2D。

我理想的想法是这样的功能:

-(CGPoint)calculateNewPointFrom:(CGPoint)p withAngle:(float)angle
{
    //Rotate point by angle in 3d space
    //Return new point in 2d space
}

2D to 3D, back to 2D

欢迎所有帮助。感谢

1 个答案:

答案 0 :(得分:0)

如果您在3D中有点Q的坐标:(x,y,z)

并且您希望将其投影到包含点P且具有法线向量n的平面上,

飞机的等式是

(R - P) . n = 0

我使用向量减法,而.是点积。

由此可以推断出任何点在该平面上的投影:沿法线向量n绘制一条直到它与平面相交的方式。

因此会有一些值a,以便

Q + a * n 

位于飞机上,即

(Q - a * n - P) . n = 0

解决(注意n . n = 1):

a = (Q - P) . n

(注意 - 这是从Q到P的“正常距离”;没有巧合!)

现在它们相交的点的值是

Q + ((Q - P) . n ) * n

再次注意 - 我正在使用矢量数学,因此最后*n会产生三个值(因为n是一个3D矢量)。

如果您尝试在平面上进行非法线投影(例如,您想投影到XY平面上,但是“正在看一个角度”),则可以对此进行概括。在这种情况下,您需要沿着不同的方向m(您正在寻找的方向)投影,并且交点的方程变为

Q + ((Q - P) . n ) * m / (m . n)

正如你所看到的,如果m垂直于n(你是沿着飞机而不是沿着它看),那就没有解决方案......

您还可以看到,如果您直接投影到XY平面上,因此n = [0 0 1]),整个过程简化为设置Z = 0

让我知道这是否足够,或者如果您需要实际的代码行......

  

---编辑---添加一些简单的代码:

如果您有一系列描述曲线的点(x,y),您可以绕Z轴(垂直于您的平面)旋转角度θ,如下所示:

x1 = x * cos(theta) - y * sin(theta);
y1 = x * sin(theta) + y * cos(theta);

现在你可以“挤压”这些点,这样你就可以从侧面看它们,只需缩小y坐标:

x2 = x1;
y2 = y1 * cos(alpha);

其中alpha是您观察曲线的视角。因此,如果您直接向下看XY平面,alpha为0,y2 = y1。如果你看45度,alphapi/4y2 = 0.707 * y1(大约)。

您可以将这两种转换合并为:

xnew = x * cos(theta) - y * sin(theta);
ynew = cos(alpha) * (x * sin(theta) + y * cos(theta));

尝试使用θ的几个值(0到0.5之间,步长为0.1)和alpha(类似范围可能很好)。看看你是否喜欢这个结果。

也许这对你来说更好(在“更有用”的意义上)?