二、 操作流程
1.插入边
1> 将Mesh里的边集与插入边集求交
如图所示:紫色线段LR插入Mesh中,与Mesh中的边AB、JE、GJ、IH、CD、DK分别交于节点M、N、O、P、Q 、R,将这些节点和节点L、S放进Mesh的节点表中。
2> 获取Mesh中被交到的边,分割它们, 将它们用分割后的子边替换
例如:将AB分割成AM和MB,然后将边AB分别从节点A和B的边表中移除,再将AM加进节点A的边表,AM和MB加进节点M的边表,MB加进节点B的边表。同时将AM和MB的边属性也设置成AB的。
3> 分割插入的线段,并将线段转成边,加进Mesh
如图所示:将LR分割成线段LM、MN、NO、OP、PQ、QR、RS,根据这些线段,生成对应的边,再将线段附加进边里,最后把这些边,加进各对应节点的边表中。
4> 搜索并处理新形成的面
遍历每个插入边,按插入边方向搜索面,判断环的时针顺序,若搜索结果为顺时针面,则处理新面的面属性、构成边的内外面、父子关系,若为逆时针面,则将该面分成小面,再处理面属性、构成边的内外面、父子关系。
如图所示:
按插入边方向搜索面:以边LM为入边,访问节点M,逆时针获取下一条边MB。发现边MB的左面存在红色面,且当前搜索该面的顺序是逆时针顺序,那么将红色面AMBCQDA分割成小面:ADQPIJNMA、QCBMNEFGHPQ、NJON、JIPOJ、PHGOP、GFENOG
设置每个小面的面属性及构成边的内面:例如面NJON,它有3条边: JN、NO、OJ,其中JN和OJ的左面为旧面(黄色面EFJG),NO为新插入边,它的左面为空,故而将新面NJON设置为它3条边的左面,并且将旧面EFJG的属性赋予新面NJON。
设置每个小面构成边的外面:
JN的右面为红色旧面ABCQDA,它为被分割面。如果它真被分割,JN的右面将是ABCQDA被分割后小面的内面,可以等到设置小面内面时设置;而如果它未被分割,则JN的右面应该保持不变,所以此时不应该改变JN的右面。
OJ的右面为蓝色旧面JGHIJ (即新面NJON的外面),对蓝色旧面而言,边OJ的右面是它的内面,所以无论蓝色面是否被分割,OJ右面都是蓝色面(或分割成的小面)的内面,在设置蓝色面或分割后小面的内面时,都会处理。故而不用处理。
NO为新插入边,它的左面已经被设置成新面,表示该边分割了黄色旧面,所以它的右面必为被分割的黄色旧面后生成的另一新面GFENOG的内面。故也可以等到设置GFENOG内面时再处理。
设置每个小面的父子关系:
如果被分割面ABCQDA有父面ParentFace,则将其子面的父面设为ParentFace,此时将被分割面从ParentFace的子面表中移除,然后将分割后的子面放入ParentFace的子面表。
2.删除边
如图2-2所示:
删除边有两种情况,
1> 将边JE删除
判断JE的内面,若有将内面(JE有内面JEFGJ)所有边的内面设置成空。
判断JE的外面,如果是父面(JE有父面ABCDA),将JE内面从其父面的子面表中移除,并将JE内面JEFGJ的所有非公共边的外面设置成空。
2> 将边GJ删除
判断GJ的内面,若有,则任选一内面(JE有内面JGHIJ),并将所有边的内外面设置成空。
判断GJ的外面,如果是兄弟面(GJ有兄弟面JEFGJ),将GJ外面(黄色兄弟面JEFGJ)从其父面的子面表中移除,并将GJ外面JEFGJ的所有非公共边的外面设置成空
如果判断一个边的外面是父面还是兄弟面,如果是兄弟面,则此边一定在兄弟面内
而如果是父面,则此边一定不在父面中。
公共边的意思是说,该边的左右两个面是兄弟面,而非公共边就是该边的左右面不为兄弟面,可能左右面都为空,可能一个面不为空,另一个为空,或者都存在,但它们是父子关系。
3.选择面
如图2-3所示:用户在虚线所示射线起点位置pt点了一下,此时应该选择出面EFGJE。那么,
2. 从pt点引一条水平向左的射线,将射线与已经存在的Mesh中的边求交,交点如图粉红色点1、2、3所示,
3. 并将交点按离pt的近远从小到大排序,排序后被交到的边依次为:GK、EF、BC。
4. 找出其中一个合格的最近的边,并获取该边的绝对右面。所谓合格,是指该边左右两面至少有一面不为空。所以GK不合格,而EF的两面都不为空,所以EF为合格边。(通过边的左右面情况确定边是否合格)
5. 获取EF的绝对右面,本来EF的右面是红色面,但它的左面相对于屏幕而言,是在右方,所以黄色面为边EF的绝对右面,故而黄色面EFGJE被选中。(为什么要用绝对右面)
4. 选择边
选择边或者点时,都会有一个允许的误差范围,本文中,把它定义为一个正方形rt,在构建网格时,作为参数传入,并且可以在构建后修改。
1. 将rt的中心移到测试点上
2. 将rt与Mesh中的边求交,找出相交边
3. 找出与测试点最近的相交边,即相交边上的交点与测试点的距离最短,该边就为选中边。
5. 选择点1. 将rt的中心点移到测试点上。
2. 在Mesh中找出在rt之内,并离测试点最近的节点,该节点即为选中点。
1.插入边
1> 将Mesh里的边集与插入边集求交
如图所示:紫色线段LR插入Mesh中,与Mesh中的边AB、JE、GJ、IH、CD、DK分别交于节点M、N、O、P、Q 、R,将这些节点和节点L、S放进Mesh的节点表中。
2> 获取Mesh中被交到的边,分割它们, 将它们用分割后的子边替换
例如:将AB分割成AM和MB,然后将边AB分别从节点A和B的边表中移除,再将AM加进节点A的边表,AM和MB加进节点M的边表,MB加进节点B的边表。同时将AM和MB的边属性也设置成AB的。
3> 分割插入的线段,并将线段转成边,加进Mesh
如图所示:将LR分割成线段LM、MN、NO、OP、PQ、QR、RS,根据这些线段,生成对应的边,再将线段附加进边里,最后把这些边,加进各对应节点的边表中。
4> 搜索并处理新形成的面
遍历每个插入边,按插入边方向搜索面,判断环的时针顺序,若搜索结果为顺时针面,则处理新面的面属性、构成边的内外面、父子关系,若为逆时针面,则将该面分成小面,再处理面属性、构成边的内外面、父子关系。
如图所示:
按插入边方向搜索面:以边LM为入边,访问节点M,逆时针获取下一条边MB。发现边MB的左面存在红色面,且当前搜索该面的顺序是逆时针顺序,那么将红色面AMBCQDA分割成小面:ADQPIJNMA、QCBMNEFGHPQ、NJON、JIPOJ、PHGOP、GFENOG
设置每个小面的面属性及构成边的内面:例如面NJON,它有3条边: JN、NO、OJ,其中JN和OJ的左面为旧面(黄色面EFJG),NO为新插入边,它的左面为空,故而将新面NJON设置为它3条边的左面,并且将旧面EFJG的属性赋予新面NJON。
设置每个小面构成边的外面:
JN的右面为红色旧面ABCQDA,它为被分割面。如果它真被分割,JN的右面将是ABCQDA被分割后小面的内面,可以等到设置小面内面时设置;而如果它未被分割,则JN的右面应该保持不变,所以此时不应该改变JN的右面。
OJ的右面为蓝色旧面JGHIJ (即新面NJON的外面),对蓝色旧面而言,边OJ的右面是它的内面,所以无论蓝色面是否被分割,OJ右面都是蓝色面(或分割成的小面)的内面,在设置蓝色面或分割后小面的内面时,都会处理。故而不用处理。
NO为新插入边,它的左面已经被设置成新面,表示该边分割了黄色旧面,所以它的右面必为被分割的黄色旧面后生成的另一新面GFENOG的内面。故也可以等到设置GFENOG内面时再处理。
设置每个小面的父子关系:
如果被分割面ABCQDA有父面ParentFace,则将其子面的父面设为ParentFace,此时将被分割面从ParentFace的子面表中移除,然后将分割后的子面放入ParentFace的子面表。
2.删除边
如图2-2所示:
删除边有两种情况,
1> 将边JE删除
判断JE的内面,若有将内面(JE有内面JEFGJ)所有边的内面设置成空。
判断JE的外面,如果是父面(JE有父面ABCDA),将JE内面从其父面的子面表中移除,并将JE内面JEFGJ的所有非公共边的外面设置成空。
2> 将边GJ删除
判断GJ的内面,若有,则任选一内面(JE有内面JGHIJ),并将所有边的内外面设置成空。
判断GJ的外面,如果是兄弟面(GJ有兄弟面JEFGJ),将GJ外面(黄色兄弟面JEFGJ)从其父面的子面表中移除,并将GJ外面JEFGJ的所有非公共边的外面设置成空
如果判断一个边的外面是父面还是兄弟面,如果是兄弟面,则此边一定在兄弟面内
而如果是父面,则此边一定不在父面中。
公共边的意思是说,该边的左右两个面是兄弟面,而非公共边就是该边的左右面不为兄弟面,可能左右面都为空,可能一个面不为空,另一个为空,或者都存在,但它们是父子关系。
3.选择面
如图2-3所示:用户在虚线所示射线起点位置pt点了一下,此时应该选择出面EFGJE。那么,
2. 从pt点引一条水平向左的射线,将射线与已经存在的Mesh中的边求交,交点如图粉红色点1、2、3所示,
3. 并将交点按离pt的近远从小到大排序,排序后被交到的边依次为:GK、EF、BC。
4. 找出其中一个合格的最近的边,并获取该边的绝对右面。所谓合格,是指该边左右两面至少有一面不为空。所以GK不合格,而EF的两面都不为空,所以EF为合格边。(通过边的左右面情况确定边是否合格)
5. 获取EF的绝对右面,本来EF的右面是红色面,但它的左面相对于屏幕而言,是在右方,所以黄色面为边EF的绝对右面,故而黄色面EFGJE被选中。(为什么要用绝对右面)
4. 选择边
选择边或者点时,都会有一个允许的误差范围,本文中,把它定义为一个正方形rt,在构建网格时,作为参数传入,并且可以在构建后修改。
1. 将rt的中心移到测试点上
2. 将rt与Mesh中的边求交,找出相交边
3. 找出与测试点最近的相交边,即相交边上的交点与测试点的距离最短,该边就为选中边。
5. 选择点1. 将rt的中心点移到测试点上。
2. 在Mesh中找出在rt之内,并离测试点最近的节点,该节点即为选中点。
200字以内,仅用于支线交流,主线讨论请采用回复功能。