美文网首页GIS加油站
二阶贝塞尔曲线生成弧线

二阶贝塞尔曲线生成弧线

作者: 牛老师讲GIS | 来源:发表于2024-01-12 08:46 被阅读0次

概述

本文分享一个二阶贝塞尔曲线曲线生成弧线的算法。

效果

image.png

实现

1. 封装方法

class ArcLine {
  constructor(from, to, num = 100) {
    this.from = from;
    this.to = to;
    this.num = num;
    return this.getPointList();
  }
  getPointList() {
    const { from, to } = this
    const ctrlPoint = this.getOffsetPoint(from, to);
    const points = this.create2PBezier(from, ctrlPoint, to)
    return points
  }
  getOffsetPoint(start, end) {
    const distance = this.getDistance(start, end) / 2; //除以3?
    let angle, dX, dY;
    const mp = [start[0], start[1]];
    const deltaAngle = - Math.PI / 8; //偏移0.2弧度
    if (start[0] != end[0] && start[1] != end[1]) { //斜率存在
      const k = (end[1] - start[1]) / (end[0] - start[0]);
      angle = Math.atan(k);
    } else if (start[0] == end[0]) { //垂直线
      angle = (start[1] <= end[1] ? 1 : -1) * Math.PI / 2;
    } else { //水平线
      angle = 0;
    }
    if (start[0] <= end[0]) {
      angle -= deltaAngle;
      dX = Math.round(Math.cos(angle) * distance);
      dY = Math.round(Math.sin(angle) * distance);
      mp[0] += dX;
      mp[1] += dY;
    } else {
      angle += deltaAngle;
      dX = Math.round(Math.cos(angle) * distance);
      dY = Math.round(Math.sin(angle) * distance);
      mp[0] -= dX;
      mp[1] -= dY;
    }
    return mp;
  }

  getDistance(p1, p2) {
    return Math.sqrt((p1[0] - p2[0]) * (p1[0] - p2[0]) + (p1[1] - p2[1]) * (p1[1] - p2[1]));
  }

  bezier2P(p0, p1, p2, t) {
    const P0 = p0 * Math.pow(1 - t, 2);
    const P1 = p1 * 2 * t * (1 - t);
    const P2 = p2 * t * t;
    return P0 + P1 + P2;
  }

  getBezierNowPoint2P(p0, p1, p2, num, tick) {
    return {
      x: this.bezier2P(p0[0], p1[0], p2[0], num * tick),
      y: this.bezier2P(p0[1], p1[1], p2[1], num * tick),
    };
  }
  create2PBezier(p0, p1, p2) {
    const num = this.num
    const t = 1 / (num - 1);
    const points = [];
    for (let i = 0; i < num; i++) {
      const point = this.getBezierNowPoint2P(p0, p1, p2, i, t);
      points.push([point.x, point.y]);
    }
    return points;
  }
}

2. 前端调用

示例使用openlayers实现。

let vetSource = new ol.source.Vector({
  features: [],
});
let vectorLayer = new ol.layer.Vector({
  source: vetSource,
  style: new ol.style.Style({
    stroke: new ol.style.Stroke({
      color: "#f00",
      width: 2,
    }),
  }),
});
map.addLayer(vectorLayer)

function addAllLines() {
  let features = [];
  for (let i = 0; i < pointData.length; i++) {
    const after = pointData[i];
    const from = [101.797439042302, 36.5937248286007];
    const to = [after.lon, after.lat].map(Number);
    let points = new ArcLine(from, to);
    points = points.map((p) => ol.proj.fromLonLat(p));
    lineData.push(points);

    features.push(
      new ol.Feature({
        geometry: new ol.geom.LineString(points),
      })
    );
  }
  vetSource.addFeatures(features);
  map.getView().animate({
    center: [12474607.173951693, 4278483.982819865],
    zoom: 3.8,
  });
}

相关文章

  • Flutter之 贝塞尔曲线(一)

    贝塞尔曲线简介 一阶贝塞尔曲线 公式 二阶贝塞尔曲线 对于二阶贝塞尔曲线,其实你可以理解为:在上利用一阶公式求出点...

  • Android贝塞尔曲线相关资料

    资料整理: Android-贝塞尔曲线 贝塞尔曲线扫盲 练习贝塞尔曲线 贝塞尔曲线绘制在线演示(带坐标) 生成三阶...

  • 贝塞尔曲线入门

    本章目录 Part One:一阶贝塞尔曲线 Part Two:二阶贝塞尔曲线 Part Three:三阶贝塞尔曲线...

  • 二阶贝塞尔曲线与 cc.Bezier

    二阶贝塞尔曲线公式如下: 看起来有一点抽象,我们来推导一下二阶贝塞尔曲线的公式,如下图: 二阶贝塞尔曲线的原理是,...

  • 贝塞尔曲线

    贝塞尔曲线 用途 贝塞尔曲线奠定了计算机绘图的基础 所有的弧线都是由贝塞尔曲线的运用 原理 依次连接开始数据点 控...

  • Android 实现波浪动画的两种方式

    一、国际惯例先上效果 二、实现思路 1、贝塞尔曲线实现 什么是贝塞尔曲线,贝塞尔曲线的原理,二阶、三阶、四阶、五阶...

  • Android-贝塞尔曲线实现水波纹动画

    Android 系统api提供了quadTo和rQuadTo实现二阶贝塞尔曲线,三阶贝塞尔曲线在这不做阐述,只不过...

  • Android--Path之贝塞尔曲线

    Path类中提供了画贝塞尔曲线的方法:quadTo()和cubicTo(),两者都是二阶贝塞尔曲线,cubicTo...

  • 贝塞尔曲线

    二阶贝塞尔曲线为了确定曲线上的一个点,需要进行两轮取点的操作,因此我们称得到的贝塞尔曲线为二次曲线. 使用三阶贝塞...

  • ios知识点(7)贝塞尔曲线

    贝塞尔曲线扫盲iOS UIBezierPath贝塞尔曲线常用方法iOS UIBezierPath(贝塞尔曲线)iO...

网友评论

    本文标题:二阶贝塞尔曲线生成弧线

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