貝塞爾曲線的數(shù)學(xué)基礎(chǔ)
有興趣的可以看一下這篇文章必須要理解掌握的貝塞爾曲線
貝塞爾曲線的數(shù)學(xué)基礎(chǔ)
賽爾曲線的本質(zhì)是通過數(shù)學(xué)計算公式去繪制平滑的曲線
-
在平面內(nèi)選3個不同線的點并且依次用線段連接
三點連線 -
在AB和BC線段上找出點D和點E,使得 AD/AB = BE/BC
AD/AB = BE/BC -
連接DE毡熏,在DE上尋找點F悄窃,F(xiàn)點需要滿足:DF/DE = AD/AB = BE/BC
DF/DE = AD/AB = BE/BC -
根據(jù)DE線段和計算公式找出所有的F點,記住是所有的F點粱挡,然后將其這些點連接起來围苫。那奄喂,連接規(guī)則是什么?以上圖為例绵脯,第一個連接點是A-F佳励,第二連接點是A-F1(這個F1必須滿足DF1/DE = AD/AB = BE/BC)以此類推,直到最后連接上C點蛆挫。
二階貝塞爾
三階貝塞爾
Openlayers實現(xiàn)貝塞爾曲線
最主要的是對公式的代碼實現(xiàn)
//階乘
function factorial(num) {
if (num <= 1) {
return 1;
} else {
return num * factorial(num - 1);
}
}
/*
* 生成貝塞爾曲線插值點
* @para n {number} 控制點數(shù)量
* @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;
}
將函數(shù)生成的點傳入Openlayers中繪制多線要素赃承,將貝塞爾曲線在地圖上進行展示。
/******************創(chuàng)建線樣式***************/
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 //類型悴侵,區(qū)別于其它Features
});
f.setId(lid); //不能刪除
f.setStyle(style);
return f;
}
/******************在地圖上標記一個點對象***************/
//隨機生成當前范圍內(nèi)的一個經(jīng)緯度坐標瞧剖,用于在地圖上標點
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];
}
/*******************在地圖初始化函數(shù)中初始化貝塞爾曲線標注層************************/
source_bezier = new ol.source.Vector();
vector_bezier = new ol.layer.Vector({
source: source_bezier
});
map.addLayer(vector_bezier);
/**************************繪制貝塞爾曲線*****************************/
function drawBezierCurve(n) {
//n表示繪制貝塞爾曲線的階數(shù)
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();
}
繪制結(jié)果:
繪制結(jié)果
貝塞爾曲線可以在地圖上實現(xiàn)軍標展示和特殊的地圖繪制