图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
}
欢迎所有帮助。感谢
答案 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度,alpha
是pi/4
和y2 = 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(类似范围可能很好)。看看你是否喜欢这个结果。
也许这对你来说更好(在“更有用”的意义上)?