美文网首页开源
Openlayers中贝塞尔曲线的绘制

Openlayers中贝塞尔曲线的绘制

作者: 宥_Hugh | 来源:发表于2019-09-26 18:32 被阅读0次

    贝塞尔曲线的数学基础

    有兴趣的可以看一下这篇文章必须要理解掌握的贝塞尔曲线

    贝塞尔曲线的数学基础
    赛尔曲线的本质是通过数学计算公式去绘制平滑的曲线
    • 在平面内选3个不同线的点并且依次用线段连接


      三点连线
    • 在AB和BC线段上找出点D和点E,使得 AD/AB = BE/BC


      AD/AB = BE/BC
    • 连接DE,在DE上寻找点F,F点需要满足:DF/DE = AD/AB = BE/BC


      DF/DE = AD/AB = BE/BC
    • 根据DE线段和计算公式找出所有的F点,记住是所有的F点,然后将其这些点连接起来。那,连接规则是什么?以上图为例,第一个连接点是A-F,第二连接点是A-F1(这个F1必须满足DF1/DE = AD/AB = BE/BC)以此类推,直到最后连接上C点。


      二阶贝塞尔
    三阶贝塞尔

    Openlayers实现贝塞尔曲线

    最主要的是对公式的代码实现

    //阶乘
    function factorial(num) {
        if (num <= 1) {
            return 1;
        } else {
            return num * factorial(num - 1);
        }
    }
    
    /*
     * 生成贝塞尔曲线插值点
     * @para n {number} 控制点数量
     * @para arrPoints {array} 控制点坐标集合
     */
    function createBezierCurvePoints(n, arrPoints) {
        var Ptx = 0;
        var Pty = 0;
    
        var arrbline = [];
        for (var t = 0; t < 1; t = t + 0.01) {
            Ptx = 0;
            Pty = 0;
            for (var i = 0; i <= n; i++) {
                Ptx += (factorial(n) / (factorial(i) * factorial(n - i))) * Math.pow((1 - t), n - i) * Math.pow(t, i) * arrPoints[i][0];
                Pty += (factorial(n) / (factorial(i) * factorial(n - i))) * Math.pow((1 - t), n - i) * Math.pow(t, i) * arrPoints[i][1];
            }
    
            arrbline.push([Ptx, Pty]);
        }
        return arrbline;
    }
    

    将函数生成的点传入Openlayers中绘制多线要素,将贝塞尔曲线在地图上进行展示。

    /******************创建线样式***************/
        function createLineStyle(color, width, linecap, linejoin) {
            return new ol.style.Style({
                stroke: new ol.style.Stroke(({
                    color: color,  //颜色
                    width: width,  //宽度
                    lineCap: linecap, 
                    lineJoin: linejoin 
                }))
            });
        }
    
        /******************绘制线***************/
        function createLine(lid, lx, arrCoordinate, style){
            var f = new ol.Feature({
                geometry: new ol.geom.LineString(arrCoordinate),
                id: lid,           //线的唯一标识
                lx: lx            //类型,区别于其它Features
            });
            f.setId(lid);  //不能删除
            f.setStyle(style);
            return f;
        }
    
        /******************在地图上标记一个点对象***************/
        //随机生成当前范围内的一个经纬度坐标,用于在地图上标点
        function randomPointJWD() {
            var topleftPoint = map.getCoordinateFromPixel([10, 10]);
            var centerPoint = map.getView().getCenter();
            var bottomrightPoint = [centerPoint[0] + (centerPoint[0] - topleftPoint[0]), centerPoint[1] + (centerPoint[1] - topleftPoint[1])];
            var jd = topleftPoint[0] + (bottomrightPoint[0] - topleftPoint[0]) * Math.random();
            var wd = bottomrightPoint[1] + (topleftPoint[1] - bottomrightPoint[1]) * Math.random();
            return [jd, wd];
        }
    
    
        /*******************在地图初始化函数中初始化贝塞尔曲线标注层************************/
        source_bezier = new ol.source.Vector();
    
        vector_bezier = new ol.layer.Vector({
            source: source_bezier
        });
    
        map.addLayer(vector_bezier);
    
        /**************************绘制贝塞尔曲线*****************************/
        function drawBezierCurve(n) {
            //n表示绘制贝塞尔曲线的阶数
            var arrPoints = [];
            for (var i = 0; i <= n; i++) {
                arrPoints.push(randomPointJWD());
            }
            var arrbline = createBezierCurvePoints(n, arrPoints);
            var style = createLineStyle("#ff2723", 4, 'round', 'round');
            var f = createLine("bezier_nj" + Math.random(), "bezier", arrbline, style);
            source_bezier.addFeature(f);
        }
    
        function clearBezierCurve() {
            source_bezier.clear();
        }
    

    绘制结果:

    绘制结果
    贝塞尔曲线可以在地图上实现军标展示和特殊的地图绘制

    相关文章

      网友评论

        本文标题:Openlayers中贝塞尔曲线的绘制

        本文链接:https://www.haomeiwen.com/subject/xfaeuctx.html