随机插入法做德劳内三角划分(递推&递归伪代码)

(随机插入法做德劳内三角划分)递推&递归

//德劳内三角剖分 RIC算法

#include <queue>
using namespace std;

// 代表一个点
struct Point {
   int X;
   int Y;
};

// 代表一个三角形
struct Trangle { 
        Point a, Point b, Point c;
};

// 返回德劳内图形DT中某点P所在的三角形 (会用到DCEL结构)
T TriangleContaining (Polyline DT, Point P) {
    //这里用一个桶来存储其中所有的点,每个桶的外边界就是一个已经剖分过的三角形
}

//找到与abc构成三角形的右边的三角形中ab边对应的点x
Point RightSite(Point a, Point b) {
    //使用DCEL 既b\a边所在三角形中的另一个顶点
    //没有返回null
}

//查看x是否在p、a、b三点构成的内接圆中
int InCircle(Point p, Point a, Point b, Point x) {
    //一个行列式 关于 a\b\x\p的四阶行列式 
    //优点:没有除法,速度O(1)
    return f(pabx); //大于0表示在圆内,小于表示在圆形外
}

//用ab替换px
void FlipEdge(Point a, Point b, Point p, Point x) {
    //这里面要操作的结构是要改变上面的存储桶三角形所包含点的位置
}

//测试固定a、b两点,与p构成的外接圆是否为空圆(圆内不存在任何点)
//如果不为空圆,则修改为最优(使用了递归)
void STest(Point p, Point a, Point b) {
    //获取从a到b直线右边的那个点(利用DCEL的双向结构)
    //(与a、b所在线段构成三角形(会有左右两个)右边的那个顶点)
    Point x = RightSite(a, b);
    //如果不存在点x在ab右侧,即ab为多边形的边界,最简单的情况,不用处理
    if(!x) return;
    //查看x是否在p、a、b三点构成的内接圆中
    if(InCircle(p, a, b, x) > 0) {
        //用ab替换px
        FlipEdge(a, b, p, x);
        //测试新增加的值得怀疑的两条线
        STest(p, a, x);
        STest(p, x, b);
    }
}

//德劳内三角形的递归做法
//测试并修复图中可疑的pa、pb、pc线(因为可能破坏结构不符合空圆要求)
void SwapTest(Point p, Point a, Point b, Point c) {
    STest(p, a, b);
    STest(p, b, c);
    STest(p, c, a);
}
//德劳内三角剖分的递推做法
//只需改变递归做法中的反转测试
SwapTest(p, a, b, c) {
    queue q = {(a, b), (b, c), (c, a)};
    wahile(!q.empty()) {
        (a, b) = q.dequeue();
        Point x = RightSite(a, b);//find t(a,x,b) on opposite side(using DCEL)
        if(!x) connect; //in case x doesnot exist
        if(InCircle(p, a, b, x)) { //if x voilates in-circle condition
            FlipEdge(a, b, p, x);//replace ab with px and
            Q.enqueue((a, x), (x, b));//insert the 2 new triangles
        }
    }
}

//在已经正确的德劳内图形中插入点P
void Insert (Point p) { 
    //首先找到包含P这个点的三角形(P在哪个三角形内部)
    Trangle T(a, b, c) = TriangleContaining(DT, p);

    //链接pa、pb、pc三条线 并插入到德劳内三角剖分图形中
    connect(p, a);
    connect(p, b);
    connect(p, c);

    //测试并修复图中可疑的pa、pb、pc线(因为可能破坏结构不符合空圆要求)
    SwapTest(p, a, b, c);
}

int main() {
     Point a, Point b, Point c;
     //假设原本是一个三角形
     Polyline DT(a, b, c);
     //不断地加入点构成更多的三角形。
     //类似于建堆
     for(int i = 2; i < points.size(); ++i) {
         Insert(points[i]);
     }
     return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值