我正在编写一些图形代码,用于实时绘制平滑连续曲线。我想添加对羽化笔刷的支持。为此,我需要能够计算“法线”,即垂直于构成我的曲线的线段的线。
纯数学方法是使用反正切函数来找到线段的角度,旋转90度,并使用正弦和余弦来找到我的法线的x和y偏移量。一旦我有了我的角度,使用查找表替换正弦和余弦会很容易,但编写一个性能高、精度低的 atan2()
似乎很棘手。
我的法线(垂直线)的长度和角度不需要精确。如果差十分之一也没关系。
你们中有没有开发出高速、粗糙版本的atan2()用于此类图形工作?优化这种性能事项是烦琐且耗时的。
我正在使用Swift 3,但我是“多语言”的。我可以很好地集成用C/Objective-C编写的代码。 (或者将其转换为Swift。)
编辑:
更多细节:
该项目涉及手绘图,提供一系列点,如果用户快速拖动手指,则有时相距很远,并使用Catmull-Rom样条添加中间点以创建一系列线段,使其足够小,看起来像平滑曲线。(Catmull-Rom样条是一种类似于较为知名的Bezier曲线的曲线,但曲线的所有控制点都位于曲线上,因此可以使用输入顶点来平滑用户“自由绘制”的曲线。)
(从现在开始,我将引用“曲线”,但实际上我指的是由线段组成的多段折线,线段长度很短,看起来像平滑曲线)
我已经将代码分解,只生成更改部分的样条曲线。现在速度非常快,可以创建与您绘制速度相同的美丽平滑曲线。主观上,似乎我正在绘制沿着您的手指轨迹逐点跟随的曲线,没有在点之间跳动。
下一个目标是能够使用软边刷绘图。为此,我想要在用户手指轨迹的左右找到与曲线平行的曲线。然后,我将使用OpenGL创建三角形带来定义左右线之间的粗曲线,并使用多边形着色从沿用户手指轨迹曲线不透明到左右平行曲线透明地模糊曲线。
假设我想要绘制一条6点宽的软边曲线。跟随用户手指轨迹的左侧和右侧的曲线都需要从用户曲线延伸3个点。
我计划通过查找垂直于用户手指轨迹的线段的线段,这些线段通过手指轨迹的顶点并向左右延伸所需线宽的1/2来找到左右曲线的端点的顶点。
下面是程序当前版本绘制的曲线的屏幕截图,其中输入顶点绘制为蓝色钻石,我添加的平滑点绘制为空心正方形。(我减少了添加的平滑点数量,以便您更好地了解情况。)
想象一下,通过每个顶点绘制一系列“哈希标记”,每个标记长6个点,以其中一个顶点为中心,垂直于平滑曲线的第一条线段,该线段以该顶点结束。
正如彼得·O在他的答案中指出的那样,找到与任何特定线段垂直的线段很容易 - 只需倒置斜率。但是,我想要特定长度的线段。(在我的示例中,6个点,每个顶点两侧各3个点。)我正在寻找快速的方法来实现这一点。我可以使用三角函数或平方根来计算我的法线的端点,但这两种方法都非常慢。
atan2
函数从math.h桥接到Darwin后速度不够快吗? - JAL