Openlayers中贝塞尔曲线的绘制
贝塞尔曲线的数学基础
有兴趣的可以看一下这篇文章必须要理解掌握的贝塞尔曲线
赛尔曲线的本质是通过数学计算公式去绘制平滑的曲线
-
在平面内选3个不同线的点并且依次用线段连接
-
在AB和BC线段上找出点D和点E,使得 AD/AB = BE/BC
-
连接DE,在DE上寻找点F,F点需要满足: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();
}
绘制结果:
贝塞尔曲线可以在地图上实现军标展示和特殊的地图绘制