zoukankan      html  css  js  c++  java
  • js之形状补间算法

    js之形状补间算法

    效果:

    从一条线形变成另外一条线,计算其中的变化过程。

    应用场景:

    1.编写从矩形缓慢变化为圆形。

    2.展示水位上升时候海岸线被淹没的过程。

    原理:

    1.将两条线个字按照长度平均分成1000份得到两个1000个点的数组。

    2.两跳线生成的数组的点一一对应。

    3.计算两个对应点中间的比例,得到中间过程中的线的数据。

    缺点:

    因为是按照长度去做的对应,如果长度在整条线上分布的不均匀,会导致中间过程中线会与预期情况偏差过大

    数据准备:(使用海岸线变化的数据举例)

    变化前的线:

    let line1 = [[111.982019, 21.757804], [113.584883, 22.176118], [113.640075, 22.825748], [114.090809, 22.373042], [114.780707, 22.612395]]

    变化后的线:

    let line2 = [[111.982019, 21.757804], [111.403052, 23.671332], [115.142303, 23.722159], [114.780707, 22.612395]]

    代码:

    function getLine(line1, line2, time) {
            // 将线换算为100个点的等距离数组
            function lineChange(line) {
              // 等分线数组
              let linec = []
          // 线分开的段数,数量越大,线越圆滑
              let amount = 100
              // 将源数据线每两个点重组为线段
              let lines = []
              // 将源数据线每两个点重组为线段的长度数组
              let linesLength = []
              // 源数据线总长度
              let allLinesLength = 0
              // 计算前面三个值
              line.forEach((e, i) => {
                if (i + 1 < line.length) {
                  lines.push([e, line[i + 1]])
                  let point1 = e
                  let point2 = line[i + 1]
                  let distance = Math.sqrt(Math.pow(point1[0] - point2[0], 2) + Math.pow(point1[1] - point2[1], 2))
                  linesLength.push(distance)
                  allLinesLength = allLinesLength + distance
                }
              })
              // 切割后每段线长度
              let lineLength = allLinesLength / amount
              // 生成平均分线的每个点
              for (let i = 0; i < amount; i++) {
                // 当前点距离起点的长度
                let length = lineLength * i
                // 当前点在第几条线段上
                let inum = 0
                for (let j = 0; j < linesLength.length; j++) {
                  if (length - linesLength[j] < 0) {
                    inum = j
                    break;
                  }
                  length = length - linesLength[j]
                }
                // 在上述循环完成后 length即当前点所在当前线段距离起点的长度
                // 当前点所在线段的起点
                let point1 = lines[inum][0]
                // 当前点所在线段的终点
                let point2 = lines[inum][1]
                // linesLength[inum]为当前点所在线段的总长度
                // 根据比例关系计算当前点坐标
                let x = (point2[0] - point1[0]) * length / linesLength[inum] + point1[0]
                let y = (point2[1] - point1[1]) * length / linesLength[inum] + point1[1]
                linec.push([x, y])
              }
              return linec
            }
            let linec1 = lineChange(line1)
            let linec2 = lineChange(line2)
            // 中间态线数组
            let arealine = []
            for (let i = 0; i < linec1.length; i++) {
              let point1 = linec1[i]
              let point2 = linec2[i]
              // 默认总动画时间为1秒
              let alltime = 1.0
              // time为传入的值,区间为0~1.表示动画运行的进度
              // 根据动画进度计算当前中间态线
              let x = (point2[0] - point1[0]) * time / alltime + point1[0]
              let y = (point2[1] - point1[1]) * time / alltime + point1[1]
              arealine.push([x, y])
            }
            return arealine
          }
     // 传入line1、line2和时间可获得当前时间线变化的中间态线
       let line3 = getLine(line1, line2, time)

    钻研不易,转载请注明出处。。。。。。。

  • 相关阅读:
    二分查找
    Android手机APN设置(中国移动 联通3G 电信天翼),解决不能上网的问题
    cocos2dx 3.1从零学习(三)——Touch事件(回调,反向传值)
    Groovy新手教程
    总结一下用caffe跑图片数据的研究流程
    JAVA数组的定义及用法
    开机黑屏 仅仅显示鼠标 电脑黑屏 仅仅有鼠标 移动 [已成功解决]
    LeetCode——Reverse Words in a String
    oracle 库文件解决的方法 bad ELF interpreter: No such file or directory
    布局文件提示错误“No orientation specified, and the default is horizontal. This is a common so...”
  • 原文地址:https://www.cnblogs.com/s313139232/p/15223763.html
Copyright © 2011-2022 走看看