快速凸包算法
凸包convexhullppt课件

Graham模版(水平序) by 吉林大学:
凸包问题:
凸包问题一般有以下两类: 1.求凸包面积周长 2.求平面最远点对
凸包面积周长 我们先来看一个问题,POJ 1113。 题意:有个贪心的国王叫他的建筑师给他的城堡周围建个围墙,他要求用最少的石
头和劳动力来建造,而且要在距离城堡某个距离L之外建造。 解法:
旋转卡壳的应用
旋转卡壳主要是用来求点集中最远点对的。如POJ 2187,就是一道求最远 点对的裸题。学会了旋转卡壳用模版可以直接过。具体参照code。
POJ 3608,求两个凸包间的最短距离。 个人解法:先求出两个凸包,然后对其中一个凸包的左下方的基准点,对
另外一个凸包求最小对应边。然后再从另外一个凸包的左下方的基准点,对前个凸
怎么从给定的点中找凸包呢?
1.卷包裹算法
2. Graham扫描算法
卷包裹算法
可以说是一个很朴素的算法,其时间复杂度最坏情况为O(n^2),其实现原理非常简 单。就像是拿了一根绳子,以最左下方的点开始,围着所有点的外围围了一圈。
先找到横坐标最小的点中纵坐标最小的点,然后以该点作为基准点,对剩余的所有
旋转卡壳算法: 这是一个非常优美而高效的算法(演示图如下):
旋转卡壳算法是解决一些与凸包有关问题的有效算法 就像一对卡壳卡住凸包 旋转而得名。被一对卡壳正好卡住的对应点对称为对踵点(Antipodal point),可以证明对 踵点的个数不超过3N/2个 也就是说对踵点的个数是O(N)的,对踵点的个数也是解决问 题的时间复杂度的保证。
while(fabs(cross(res[p+1],res[p],res[q+1]))>fabs(cross(res[p+1],res[p],res[q]))) q=(q+1)%n;
基于凸包算法的指尖识别方法

基于凸包算法的指尖识别方法高晨;张亚军【摘要】针对现有指尖检测方法容易受背景的干扰,并且指尖误判点较多的情况,提出了一种基于凸包分析的指尖检测算法.首先,为减少类肤色背景和光照对手部轮廓提取的影响,采用YCbCr肤色模型和背景差分法相结合的方法提取手部轮廓;然后采用快速凸包算法获得手部轮廓的凸包,并利用凸包顶点和缺陷点计算出掌心的坐标,根据凸包缺陷深度和手指几何特征及曲率特征检测手指指尖;最后采用有灯光和类肤色背景干扰的环境,而不是背景单一的环境进行实验,验证了所提算法的鲁棒性.实验结果表明,该算法可以有效识别出指尖数目和手掌的位置,实现简单的数字手势(0~5)的识别,具有较强的鲁棒性.%Since the conventional fingertip detection method is easily influenced by background and there are too many finger misjudgment points,this paper proposes a detection algorithm based on the analysis of a convex hull.Firstly,in order to reduce the influence of approximate skin background color and light intensity on the extraction of the hand area,we use the YCbCr skin model combined with the background difference method to extract the hand area.We then derive the hand contour convex hull and,finally,use the defects and hull points to obtain the coordinates of the hand palm.Based on the depth of the convex hull defects,the geometric features of fingers and curvature allow detection of the fingertips.In order to verify the robustness of the algorithm developed in this paper,we employed a light and colored background,rather than a single background environment;the results showed that the method can effectively identify the number of fingertipsand the location of the palm,and can also recognize numerical (0 ~ 5) hand gestures,demonstrating its efficacy.【期刊名称】《北京化工大学学报(自然科学版)》【年(卷),期】2017(044)002【总页数】6页(P70-75)【关键词】指尖识别;凸包算法;背景差分法;肤色模型【作者】高晨;张亚军【作者单位】北京化工大学机电工程学院,北京 100029;北京化工大学机电工程学院,北京 100029【正文语种】中文【中图分类】TP301.5手势作为人们常用的表达方式之一,可以快速简单地实现人机交互,代替传统的键盘、鼠标等人机交互设备。
凸包算法公式

凸包算法公式凸包是计算几何中的一个重要概念,而凸包算法公式则是解决相关问题的关键工具。
咱先来说说啥是凸包。
想象一下,你面前有一堆散落在地上的钉子,然后你拿一个橡皮筋把最外层的钉子圈起来,让橡皮筋形成的形状能够完全包住所有钉子,这个形状就是这堆钉子的凸包。
凸包算法有好几种,比如 Graham 扫描法、Jarvis 步进法等等。
咱就拿 Graham 扫描法来说说它涉及的公式。
Graham 扫描法里,首先要找到一个基准点。
通常找纵坐标最小的点,如果有多个这样的点,就选横坐标最小的那个。
找到这个点后,其他点就按照和这个基准点的极角大小进行排序。
这里就涉及到计算极角的公式啦。
对于两个点 A(x1, y1)和 B(x2, y2),极角θ 可以通过反正切函数来计算,公式是:θ = atan2(y2 - y1, x2 - x1)。
计算出极角后,就可以开始扫描了。
从基准点开始,依次检查相邻的三个点,如果这三个点构成的转向是逆时针的,那就保留中间那个点;如果是顺时针的,就把中间那个点去掉。
这里判断转向的公式就比较关键了。
对于三个点 A(x1, y1)、B(x2,y2)和 C(x3, y3),可以通过计算向量叉积来判断转向。
如果叉积大于 0 ,就是逆时针;小于 0 ,就是顺时针。
向量叉积的公式是:(x2 - x1) * (y3 - y1) - (y2 - y1) * (x3 - x1) 。
我记得之前有一次参加数学建模比赛,题目就和凸包算法有关。
当时我们小组几个人,一开始对这些公式和算法都不太熟悉,急得像热锅上的蚂蚁。
大家一起熬夜查资料、讨论,一遍遍地推导公式,尝试不同的方法。
特别是在计算极角和判断转向的时候,总是出错。
但经过不断地尝试和纠错,我们终于搞清楚了这些公式的应用,成功解决了问题,还拿到了不错的名次。
总之,凸包算法公式虽然看起来有点复杂,但只要掌握了其中的原理和规律,多做练习,就能熟练运用啦。
不管是在数学研究中,还是在实际的计算机图形学、地理信息系统等领域,凸包算法都有着广泛的应用。
凸包算法

长 江 大 学 地 球 科 学 学 院
遗留有一个问题 就是处理共线的问题 有时候我们需要凸包边上的点也考虑到 有时候却需要去掉这些点 我们通常称在凸包顶点处的点为极点 如果我们只要求保留极点而去除在边上的点 我们只需在取外侧的点的时候 碰到共线的点取最远的 相反 如果我们要保留所有在边上的点我们只需要在共线的点中取最近的 同样由于参考点的性质 所有向量之间的到角都是在180度以内 不会产生错误
我们经常关注一个点集的凸包 这也是计算几何学的一个基本问题,现在 已经有成熟的算法可以求出平面点集的凸包,凸包有着优美而实用的 性质 我们可以利用凸包把一个杂乱的点集所包含的信息进行有效的 概括、梳理。
2 Graham扫描算法(Graham Scan Algorithm)
Graham扫描算法维护一个凸壳 通过不断在凸壳中加入新的点和去除影响 凸性的点 最后形成凸包 算法主体由两部分组成 先是排序 后是扫描 分块讲解一下
void Graham(int n) { int i,top=2; Pt[n]=Pt[0]; Stack[0]=Pt[0]; Stack[1]=Pt[1]; Stack[2]=Pt[2]; for(i=3;i<=n;i++) { while(Cross(Stack[top1],Stack[top],Pt[i])<=0&&top>1) top--; Stack[++top]=Pt[i]; } }
有了向量 我们就可以选取一个最外侧的点了
长 江 大 学 地 球 科 学 学 院
利用向量 我们可以比较哪个点"更外侧" 比如点K和点I 我们利用向量JK乘以向量JI得到一个数 这 个数应该是负数 说明I比K更外侧 两个向量的比较具有传递性 所以我们可以像N个数里取 最大的数一样取出最外侧的 遍历所有点 每个点都和现有最外侧的点比较 得到新的最 外侧的点
凸包面积和周长的计算

凸包面积和周长的计算凸包是在平面上给定的一组点中构成的最小凸多边形。
凸包的面积和周长是计算凸包重要的指标,可以用来分析数据分布的紧密程度和形状特征。
本文将介绍凸包的定义和生成算法,并详细说明如何计算凸包的面积和周长。
一、凸包的定义凸包是指在平面上给定的一组点中,由这些点构成的最小凸多边形。
凸多边形的特点是:任意两点之间的线段都在多边形内部。
凸包是凸多边形中的最小面积的凸多边形,即是在所有凸多边形中,面积最小的凸多边形。
二、凸包的生成算法1. Jarvis算法(也叫作包裹算法或者旋转卡壳算法):该算法基于以下思想:从一组点中找到一个起始点,将其作为凸包的一个顶点。
然后,从这个点开始,寻找下一个能保证凸包深度最大的点,并将其加入凸包。
不断重复这个过程,直到回到起始点为止。
该算法的时间复杂度为O(nh),其中n是点的个数,h是凸包的顶点数。
2.快速凸包算法:该算法基于Graham扫描算法改进而来。
首先选择一个y坐标最小的点,将其他点按照与这个点的连线的极角进行排序。
然后依次处理排序后的点,对每个点进行判断,如果点在逆时针方向上,则加入凸包,否则舍弃。
最后得到凸包。
该算法的时间复杂度为O(nlogn),是一种高效的凸包生成算法。
三、凸包面积的计算凸包的面积可以用以下公式进行计算:S = (x1y2 + x2y3 + ... + xn-1yn + xny1 - x2y1 - x3y2 - ... - xnyn-1 - x1yn) / 2其中,(x1, y1), (x2, y2), ..., (xn, yn)是凸包的顶点的坐标。
计算凸包的面积可以通过以上公式进行求解,公式中的坐标是有顺序的,要按照逆时针或者顺时针的方向依次输入。
四、凸包周长的计算凸包的周长可以通过计算凸包顶点之间的距离之和来得到。
对于凸包的n个顶点,可以依次计算相邻顶点之间的距离,并将其累加得到凸包的周长。
保证计算的正确性需要注意以下几点:1.凸包的顶点要按照逆时针或者顺时针的方向依次输入,以保证计算出的面积和周长的结果正确。
多边形化算法

多边形化算法
多边形化算法是指将给定的点集或线段组合成封闭的多边形的过程。
这个问题在计算几何学、计算机图形学和地理信息系统等领域中经常遇到。
以下是一些常见的多边形化算法:
1. 凸包算法:凸包算法是最常用的多边形化算法之一。
它的目标是找到包含所有点的最小凸多边形。
常见的凸包算法有Graham扫描算法、Jarvis步进算法和快速凸包算法。
2. 三角剖分算法:三角剖分算法将给定的点集或线段划分为一组互不相交的三角形,从而形成多边形。
常见的三角剖分算法有Delaunay三角剖分算法和Ear Clipping算法。
3. 最小生成树算法:最小生成树算法可以用于生成一个连接给定点集的最小权重树形结构,在某些情况下可以用来构建多边形。
Prim算法和Kruskal算法是两种常用的最小生成树算法。
4. Alpha形算法:Alpha形算法是一种基于给定参数Alpha 的多边形化算法。
它通过连接在给定距离内的点来构建多边形,从而生成不规则的凸多边形。
5. Voronoi图算法:Voronoi图算法将给定的点集划分为一组区域,其中每个区域都由距离最近的点支配。
这些区域可以被视为多边形的一部分。
这些算法在实际应用中根据具体需求和数据特征的不同,选择合适的算法进行多边形化处理。
需要根据具体情况评估算法的效率、精确性和适用性。
计算机位图的快速凸包算法

的横 坐标 ,PY 示 P .表 点的纵 坐标 。
定 义2 设 S { () () = P 1,P 2 ,… ,P n ) 平面 ()是
收稿 日期 :2 1— 9 0 01 0— 3 作者简介 :陈辉 (9 2一 18 ),男,河北廊坊人 ,助理工程师 ,主要从事 计算机相关研究 。
[0 ] 第3卷 12 4
中田分类号 :T 1 P3 2 文献标 识码 :A 文章编号 :1 0 — 14 2 1) l - 一 1 2 O 9 0 ( 0 2 O (I 0 一 3 0 3 ) 0
D i 1 . 9 9 j 1s . 0 9 1 4 2 1 . 1 ) 3 o : 3 6 / . n 1 0 -0 . 0 2 0 (E . 2 0 s 3
直 是 国 内外 研 究 的热 点 。因 为 这 个 问题 是 计 算
几 何 的 基 本 问 题 之 一 ,人 们 对 此 做 出 了 很 多 的 工 作 ,从 理 论 上 证 明 了 凸包 算 法 的最 低 复 杂度 是 O( lg )】 no n ,并 且提 出 了很 多好 的算 法 ,这 些 算法 都达 到 了理 论 上 的 复杂 度下 限O(lg )】 no n 。如 后面
的点 可 以 被 分 为4 0 ,而 在这 4 0 中 , 只有它 8类 8类
提 到 的Grh m 算 法 ,和 北 大 的教 授 周 培 德 先生 aa 提 出的Z . ,算法 和 Z_ ] 3[ 2 算法 。但 是其 平均 性能 却都 8
和最 坏情 况下 的性 能相 同 ,即都 是O(lg ) no n 。
第1 期
21— 1上 ) 02 0 (
-
l
匐 出
可 能 的 中间 点 已 经 不 多 于4 0 个 ,剩 -‘ 8 ×2 p的点 只 要选 取一 种 现有 的算 法 它的 复杂 度也 必 然很 低 。
凸包算法及凸包融合

凸包算法及凸包融合凸包算法是计算凸包的一种常用算法,它可以找到一组点集中最外层的凸多边形。
凸包融合是指将两个凸包合并成一个新的凸包,能够通过减少顶点数目来优化计算效率。
凸包算法主要有以下几种常见的实现方法:1.枚举算法:对于点集中的每一对点,判断其他点是否位于这两点所确定的直线的一侧。
如果所有点都在一侧,则这两点是凸包上的边。
时间复杂度为O(n^3)。
2. Graham扫描算法:选取一个点作为基准点,将其他点按照相对于基准点的极角大小进行排序。
然后依次处理每个点,判断其是否属于凸包。
时间复杂度为O(nlogn)。
3. Jarvis步进算法(也称为包裹法):从点集中选取一个临时点p,然后找到与p相邻的点集中极角最小的点q,将q加入凸包中。
然后将q作为新的临时点p,重复以上步骤,直到回到第一个点。
时间复杂度为O(nh),其中h是凸包的边数。
4.快速凸包算法:通过空间分割和递归的方法进行凸包计算,时间复杂度为O(nlogn)。
凸包融合是指将两个凸包合并成一个新的凸包,通常需要满足以下条件:1.相交边的共享:两个凸包如果相交,那么它们的公共边必须都在新的凸包中。
2.外部边的合并:如果两个凸包没有相交,那么合并后的凸包应该包含两个凸包的外部边。
3.顺序性:合并后的凸包应该按照某种规定的顺序进行连接。
凸包融合算法的一种常见方法是基于边的融合。
具体步骤如下:1.找到两个凸包之间的最近边,并将其作为起始边。
2.沿着其中一个凸包的边界向对面的凸包前进,每次选取与当前边最接近的边。
3.如果新选取的边与已经选取的边形成了一个角度大于180度的三角形,那么停止前进,并将新选取的边作为起始边。
4.重复步骤2和步骤3,直到回到起始边。
凸包融合算法可以减少凸包的顶点数量,从而提高计算效率。
例如,对于两个有m和n个顶点的凸包,假设m > n,则融合后的凸包最多有m+n个顶点,而不是m*n个顶点。
融合后的凸包可以保留原始凸包的边界信息,并且减少了计算和存储开销。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
2.5 Graham算法
• 以极端点 pi为初始点, • 依次对相邻三个点pi ,pi+1和pi+2 ,计算pi pi+1×pi+1pi+2
– 如果在z 轴上的投影大于零,即(pi pi+1×pi+1pi+2)z>0
• 说明在pi+1 处左转弯,多边形在该点上外凸,暂时保留这三点 • 前进一步,同样去判断相邻三个点pi+1,pi+2和 pi+3
– 二面角是指空间中两个相邻接的面在它们的公共边上的内夹角
• 对于任意的多胞形,顶点处的所有多边形内角之和小于2π
– 这是每个顶点处是凸的必要条件,但不是充分条件
3.1 多面体
• 3.1.2 正则多面体
– 只存在五种不同的正多面体
• 正四面体、正六体、正八面体、正十二面体和正二十面体 • 也叫柏拉图体(Platonic solids),因为柏拉图在他的《蒂迈 欧篇 (Timaeus) 》中讨论过它们
3.1 多面体
• 如果把多面体看成厚度为零的多边形围成的空间, 第二个条件也可写为
– 多面体表面上任一点,它在表面上的邻域同胚于一个 开圆盘,开圆盘是二维的开圆 – 如果一个表面上的每一个点都满足这个条件,那么这 个表面就被称为二维流形(2D manifold)
3.1 多面体
• 第3个条件表示顶点和边组成的图是连通的
– 如果(pi pi+1×pi+1pi+2)z ≤0
• 说明在pi+1处右转弯,多边形在该点上内凹,把pi+1点从多边形边界中删除 • 后退一步,同样去判断相邻三个点pi-1,pi和 pi+2
• 时间复杂度为线性O(n)
凸包计算方法对比
• 极端边算法O(n3)
• 礼品包裹算法O(n2) • 快速算法
2.4 凸包的快速算法
• 算法过程
– 取两个极端点,它们是最右最下点pdr和最左最上点pul – 有向直线 pdr pul将整个凸包被划分为右凸包和左凸包 – 对右凸包和左凸包分别进行递归
– 递归
• • • • • 设S1是严格在直线 pdr pul右边的点集(S1可能是空集) 在S1中寻找距离直线 pdr pul最远的点,作为pdr pul右边的一个极端点b 连接pdr和b ,及b 和pul 把pdr右侧的点集记为A, pul右侧的点集的点记为B 对边pdr b和点集A、对边b pul 和点集B分别递归调用
• 多面体表 • 如果把多面体看成一个实心的实体,表面上任一点的足够小的 邻域同胚于一个三维的如下定义的半开半闭的半球。半开半闭 的半球定义为x2+y2+z2<r2和z≤0的交,其中r为半球的半径 • 多面体表面是连通的,即表面上任意两点可通过完全在表面上 的路径连接
2.4 凸包的快速算法
• 算法过程
– 递归
• • • • • 设S1是严格在直线 pdr pul右边的点集(S1可能是空集) 在S1中寻找距离直线 pdr pul最远的点,作为 pdr pul右边的一个极端点b 连接 pdr和b ,及b 和 pul 把 pdrb右侧的点集记为A, bpul右侧的点集的点记为B 对边 pdrb和点集A、对边bpul 和点集B分别递归调用
3.1 多面体
• 两个集合是同胚的(homeomorphic)
– 三黑点的邻域都不能同胚于一个三维的半开半闭的半球 – a和b中黑点的邻域同胚于两个接触于一条线或一个点的 三维的半开半闭的半球 – c中黑点的邻域是同胚于半个二维开圆盘
3.1 多面体
• 3.1.1 多面体定义
– 三维空间中的多面体是由有限个平面多边形围成的区 域,其边界满足下列三个条件
Advanced Graphics
孙晓鹏
博士 教授
cadcg2008@
2011年 11月 16日
第二章 二维凸包
2.4 凸包的快速算法
• 主要思想
– 点集S 的凸包是取决于凸包边界附近的点 – 逐步丢掉凸包内部的点,只关注凸包附近的点,从而 提高算法的效率 – 最好情况O(nlogn)、 最坏情况O(n2)
– 三维礼品包裹算法从凸包的一个面f开始
• 选择面f上的一条边e • 将f所在的平面π,沿着e朝着点集折叠,直至碰到第一个点p, 则{p,e}成为凸包的一个新的三角面片 • 重复上述操作
3.2 三维凸包算法
• 3.2.1 礼品包裹算法
– 算法起始需要确定凸包上的一个面f
• 首先把点集中的所有三维点投影到yz坐标平面上得到一个二维 点集 • 然后求这个点集在二维空间中的一条极端边,要求该边的一个 端点是z坐标最小的一个点 • 设这极端边的两个端点对应的三维点为pi和pj,则pipj为三维空 间中点集凸包的一条边 • 构造一平面π通过pipj且其法线垂直x坐标轴 • 再对π绕着pipj旋转,直至碰到第一个点p
2.4 凸包的快速算法
– 最好情况出现在每次划分均是平衡的, O(nlogn) – 最坏情况出现在每次划分点的分布都很极端, O(n2)
2.5 Graham算法
• 20世纪60年代末
– 贝尔实验室需要求解10,000个点的凸包 – O(n2)的方法太慢
• 1972年
– Graham出O(nlogn)的二维凸包算法
– 最好情况O(nlogn)、 最坏情况O(n2)
• Graham 算法
– 排序计算O(nlogn)、执行时间O(n) – 总的时间复杂度O(nlogn)
第三章 凸包扩展
3.1 多面体
• 两个集合是同胚的(homeomorphic)
– 指它们之间存在一个连续的一一映射 – 并且这个映射的逆映射也是连续的 – 两个同胚的集合允许它们各自拉伸和扭曲,但只要 不撕裂,其结果仍然同胚 – 如果任一集合被撕裂了,映射的连续性便被破坏, 两个集合就不再同胚了
– 排除那些有“浮在”表面里面的顶点和边的物体
3.1 多面体
• 多面体可以存在“通孔(hole)”,从多面体表面的一面通到另一面 • 多面体允许有任意多个这样的孔,孔的数目叫做这个体的亏格(genus)
– 亏格为0的多面体在拓扑上同胚于球 – 亏格为1的多面体在拓扑上同胚于圆环面
• 凸多面体又叫做多胞形,为了强调它们是三维的,有时也叫做三胞形 • 多胞形是凸多面体,连接它上面的任意两个点的线段都在多胞形内部 • 凸多边形在每一个顶点处是凸的 • 多胞形在每一条边处的所有二面角(dihedral)都是凸的(≤π)
– 依次连接凸包上的顶点,得点集S1的凸包,即点集S的右凸包 – 类似地,计算出点集S的左凸包,从而得到整个点集S的凸包
2.4 凸包的快速算法
• 算法过程
– 取两个极端点,它们是最右最下点pdr和最左最上点pul – 有向直线 pdr pul将整个凸包被划分为右凸包和左凸包 – 对右凸包和左凸包分别进行递归
2.5 Graham算法
• 基本思想
– 在凸包内部找到一个点o
• 如S 中任何三个不共线的点的重心,O(1)
– – – –
将o作为极坐标的中心,计算每个点的极角θ 对S中的点按θ升序排列(如pi ,pi+1 , pi+2),O(nlogn) 计算相邻三点转角的凹凸性,删除内凹的点O(n) 当点集内不再包含内凹的点时,得到凸包
• 最坏情况下,三维礼品包裹算法的时间复杂度O(n2)
3.2 三维凸包算法
• 3.2.2 分而治之算法
– 分而治之算法的时间复杂度下界也为Ω(nlogn)
– 则{p,pipj}便是平面f
3.2 三维凸包算法
• 3.2.1 礼品包裹算法
– 确定一个面片需要O(n)时间 – 设F为凸包上面片的数目
• 三维礼品包裹算法时间复杂度为O(nF)
– 三维礼品包裹算法也具有输出大小敏感特性
– 由定理3.1得知,n个顶点的多面体面片数是O(n) – 凸包面片的数目也有可能达到O(n)
• 定理3.1
– 对于一个顶点数v=n,边数与面数分别为e和f的亏格为0的多面体, 有 v – e + f = 2,且e和f都为O(n)
3.2 三维凸包算法
• 3.2.1 礼品包裹算法
– 礼品包裹算法适用于任意维点集的凸包构建 – 三维礼品包裹算法是二维的直接扩展
– 二维礼品包裹算法从凸包的一条边开始
3.1 多面体
• 3.1.3 多面体的欧拉公式
– 1758年,Leonard Euler – 亏格为0的多面体的顶点数、边数和面数规律
• 顶点数和面数之和总是比边数多2 • 正方体有8个顶点和6个面,8+6=14,比边数12大2
– 用v、e、f分别表示多面体顶点、边和面的数目 – 欧拉公式:v – e + f = 2