微积分用来解决的问题通常是定量类的,比如算速度,路程,斜率,面积等等,而绕序却是一个定性的问题,非黑即白,两者完全扯不上关系。所以在很长一段时间里,我在解决绕序的事情上并没有往着微积分方向去想。但它们的关系竟然密不可分。
由于表面上扯不上关系,所以我们先来看看,微积分中最基本的运算在几何学上解决的最常见问题——图形面积
假设有一条曲线的函数表达式为y=f(x),那么有一个微积分公式是这样的
它算出来的值代表下图填色部分的面积,即f(x)在[a,b]区间内的图像和x=a,x=b,以及x轴所围成的图形的面积。
有了这样一个公式,我们就可以计算一些曲边图形的面积了。
同济大学高等数学教材有一道题目是这样的。
求y=sqrt(x)和y=x²所围成的图形的面积。
首先,两个函数的交点为(0,0)和(1,1),所以积分的区间是[0,1] 我们把这两个函数的积分计算式子写出来。
和
它们分别代表图中红色和蓝色部分的面积
红和蓝相减,就得到所求部分的面积了。
同样地,不带曲边的多边形也能用类似的方法进行实现。
比如下图的三角形。
用红+绿-蓝即可得到
我在三维家讲课的时候,这3块图形没有分开来放,而是在ppt中以动画的形式逐块显示。但此处我偷懒了,不想再做动画。
3个都是直角梯形,计算面积的时候无需进行任何微积分的计算,但是这个加减的套路却来源于微积分。因此可以说,这就是运用了微积分思想,但没有用到具体微积分公式的一个体现。
我们用肉眼可以看出红和绿是加,蓝是减,那程序要如何知道呢?让我们先来看看程序存储多边形的方式。
程序存储不带曲线的多边形,一般都按着顺序存储多边形上的点,然后在绘制多边形的时候会顺着点的顺序一根根地给画出来。
我们用箭头表示下 红色和绿色所对应的箭头是往右走的,它们对应的面积部分是加。蓝色所对应的箭头是像左走的,它们对应的面积部分是减。对于这个图形来说,看线条走向就能确定加减了。
好了,我们来试一下复杂点的图形这一做法是否还正确。这次就没办法偷懒了,不然图片太多。
下面的演示动画中,红色代表加,绿色代表减,蓝色代表当前面积部分。
x前后一致的(比如4-5),面积为0,无所谓正负了 经过反复的加加减减,得到的正是图形自身的面积!
现在有个新的问题来了:点要是反着走呢?箭头方向不是全反了?
从上图我们不难发现,顺时针走的,是右为加,左为减,逆时针走的,是右为减,顺为加。
所以在确定加减的时候,还得判断一次绕序。然后蛋疼的事情来了,我们在上一篇判断绕序的时候,遇到了很多蛋疼的问题,要处理很多特殊的情况,难道这里还是绕不开么?
再好好思考下,面积不是右-左就是左-右,而且在绕序变反了之后,所有的线都是一起变的,所以哪怕算出来的结果不正确,它跟正确结果的区别仅仅是一个正负号!
这样,我的灵感突然就来了。
绕序一变,面积的大小不变,符号变反。那是不是就意味着,可以用面积的符号来确定一个图形的绕序呢?
答案当然是肯定的!!! 像上面的图,就是顺时针绕序,面积为正,逆时针绕序,面积为负。
因此,用面积符号代替凸角来判断绕序,就能巧妙避开很多的特殊处理了! 而这个带符号的面积,被称作这个图形的有向面积,它指示了图形的绕序方向。
凸角法需要处理的特殊情况,相当一部分是0度或者180度这种导致叉积接近0的位置,浮点误差很容易使它们的正负性发生改变从而出现误判。
因此,对于面积来说,如果有向面积很接近0,那么也会有同样的问题。
所幸的是,有向面积很接近0,它的真实面积也很接近0(看着就像一根线),对于0面积的图形,我们只要剔除掉就可以了,99.99%的情况,0面积的图形没有任何意义。而且0面积的图形,无所谓正反绕序,我们看看下图,你说它逆的或者顺的都有道理。
然后,图形本身有边发生自相交也会算出面积为0。 这种图形被称作缠绕型多边形,在我们的项目里不存在,会将其拆成两个独立的图形来处理。 此处上半部分为顺时针,下半部分为逆时针,所以也无所谓绕序的正反了。
最后再指出一点,如果曲线带了弧线,并且一段弧线中既有向左也有向右的部分,那我们应该拆成两部分进行处理,或者使用诸如参数方程的形式,用参数代替x作为积分变量构建一对一的关系进行积分计算。考虑到这是第一个案例,我不打算给大家讲解跟微积分具体计算有关的事情。
综上所述,忽略掉无意义的情况,用有向面积可以有效绕开接近0位置的浮点误差问题,让绕序的判断更加精确
用面积判断绕序,看起来似乎很简单,但这当中却蕴含了丰富的微积分思想,很有深入浅出的味道。
这,就是我第一次在工作中用到微积分的案例了。
判断绕序的问题曾经困扰了我们将近半年的时间。总结下来,原因有那么几个:
1 我入职公司后有点闭门造车了,在需求扩展的时候仍然过度迷信旧的算法。
2 每次遇到特殊情况都觉得只要加入特殊判断或者处理就能绕过,无需进行大改。
3 即使有时候打算在网上寻求更好的解决方案,也觉得我的问题是因为加了圆弧才产生的,网上的文章都只讲直边,对自己没任何帮助。
而事实上,这套做法在csdn上都能找到不少文章了,比如下面这篇。
https://blog.csdn.net/u012138730/article/details/79814650
而且跟微积分相比,有向面积判断绕序的做法跟向量数学的关系更为密切。最直接的一点,向量叉积可用于计算三角形面积,得到的结果也带有符号,其正负也正好指示了三角形的绕序。
所以就这案例来说,把微积分搬出来似乎有点小题大做了,但这仅仅是个开始。既然用到了弧线,那么微积分将会被越来越多地被应用到项目之中。因此接下来,我会给大家分享更多更精彩的微积分案例,敬请期待!