成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

n階貝塞爾曲線(bezier)javascript 實(shí)現(xiàn)解析

Labradors / 2178人閱讀

摘要:最近學(xué)習(xí),看到曲線,所以補(bǔ)充了下知識,另外相關(guān)的數(shù)學(xué)定律都忘光了需要了解的前期需要了解相關(guān)的知識,可以看下維基百科什么是貝塞爾曲線什么是線性插值繪制本身只提供了二次和三次的繪制函數(shù),如果更高階級的怎么辦呢要對起進(jìn)行降階拆分。

最近學(xué)習(xí)canvas,看到bezier曲線,所以補(bǔ)充了下知識,另外相關(guān)的數(shù)學(xué)定律都忘光了~

需要了解的

前期需要了解相關(guān)的知識,可以看下維基百科

什么是貝塞爾曲線?

什么是線性插值?

繪制

canvas本身只提供了二次和三次的繪制函數(shù),如果更高階級的怎么辦呢~要對起進(jìn)行降階拆分。

網(wǎng)上有個(gè)很牛掰的案例 bezier curve

我們來看下這個(gè)案例的js,這個(gè)demo并沒有像我們的方程式寫的那樣來進(jìn)行計(jì)算,但是它用了遞歸的操作,遞歸調(diào)用draw方法,來實(shí)現(xiàn)層層的繪制

var input = document.getElementsByTagName("input")[0]
var span = document.getElementsByTagName("span")[0]
var div = document.getElementsByTagName("div")[0]
var ctx1 = document.getElementsByTagName("canvas")[0].getContext("2d")
var ctx2 = document.getElementsByTagName("canvas")[1].getContext("2d")
var ctx3 = document.getElementsByTagName("canvas")[2].getContext("2d")

var points = [], colors = [], running = true, steps = 200, interval = 16, num

ctx1.font = "16px consolas"
ctx1.fillStyle = ctx1.strokeStyle = "hsl(0, 0%, 50%)"
ctx1.lineWidth = ctx2.lineWidth = 2
ctx3.strokeStyle = "hsl(0, 90%, 70%)"

function count() {
  num = parseInt(input.value)
  span.innerHTML = num
}

function toggle() {
  input.disabled = running = !running
}

function draw(per, arr, color) {
  var ary = []
  var node

  ctx2.strokeStyle = ctx2.fillStyle = colors[color]

  node = arr.reduce(function(previous, current, index) {
    // 從第二個(gè)元素開始,第二個(gè)點(diǎn),這時(shí)候index為1,計(jì)算得到p點(diǎn),index為1的時(shí)候,p點(diǎn)為bezier開始點(diǎn)到第一個(gè)控制點(diǎn)的插值
    // 第三個(gè)元素的時(shí)候,第三個(gè)點(diǎn),index為2,計(jì)算得到p點(diǎn),index為2的時(shí)候,p點(diǎn)為第一個(gè)控制點(diǎn)向第二個(gè)控制點(diǎn)移動(dòng)的插值
    var p = {x: arr[index - 1].x + (arr[index].x - arr[index - 1].x) * per, y: arr[index - 1].y + (arr[index].y - arr[index - 1].y) * per}

    if(index > 1) {
      // 當(dāng)達(dá)到第二個(gè)控制點(diǎn)的時(shí)候,獲取從開始點(diǎn)到第一個(gè)控制點(diǎn)的p,進(jìn)行l(wèi)ine
      ctx2.beginPath()
      ctx2.moveTo(previous.x, previous.y)
      ctx2.lineTo(p.x, p.y)
      ctx2.stroke()
      ctx2.closePath()
    }
    // 繪制當(dāng)前的插值點(diǎn)
    ctx2.beginPath()
    ctx2.arc(p.x, p.y, 3, 0, Math.PI * 2, true)
    ctx2.fill()
    ctx2.closePath()
    // 將坐標(biāo)點(diǎn)push到新的坐標(biāo)數(shù)組中
    ary.push(p)
    return p
  })

  if(ary.length > 1) {
    // 將插值作為新的開始點(diǎn)和控制點(diǎn)進(jìn)行繪制,就這樣遞歸下去
    draw(per, ary, color + 1)
  } else {
    // 如果插值的數(shù)組只有1個(gè)值,繪制的就是bezier曲線上的點(diǎn),從起點(diǎn)一點(diǎn)一點(diǎn)連到結(jié)束點(diǎn)
    ctx3.lineTo(node.x, node.y)
    ctx3.stroke()
  }
}

var drawAsync = eval(Wind.compile("async", function () {
  toggle()
  ctx3.beginPath()
  ctx3.moveTo(points[0].x, points[0].y)
  for(var i = 0; i <= steps; i++) {
    draw(i / steps, points, 0)
    $await(Wind.Async.sleep(interval))
    ctx2.clearRect(0, 0, 800, 600)
  }
  ctx3.closePath()
  points = []
  toggle()
}))

div.addEventListener("click", function(e) {
  if(running) {
    return
  }

  var point = {x: e.pageX - div.offsetLeft, y: e.pageY - div.offsetTop}

  if(points.length == 0) {
    ctx1.clearRect(0, 0, 800, 600)
    ctx2.clearRect(0, 0, 800, 600)
    ctx3.clearRect(0, 0, 800, 600)
  } else {
    ctx1.beginPath()
    ctx1.moveTo(point.x, point.y)
    ctx1.lineTo(points[points.length - 1].x, points[points.length - 1].y)
    ctx1.stroke()
    ctx1.closePath()
  }

  ctx1.beginPath()
  ctx1.fillText("[" + point.x + ", " + point.y + "]", 15, 25 * (points.length + 1))
  ctx1.arc(point.x, point.y, 4, 0, Math.PI * 2, true)
  ctx1.fill()
  ctx1.closePath()

  points.push(point)

  if(points.length == num) {
    drawAsync().start()
  }
}, false)

input.addEventListener("change", count, false)

window.addEventListener("load", function() {
  for(var i = 0; i < parseInt(input.max); i++) {
    colors[i] = "hsl(" + 60*(i + 1) + ", 60%, 60%)"
  }
  count()
  toggle()
}, false)
總結(jié)

讓我自己寫還真寫不出來。。。對array.reduce的用法真的爐火純青了

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/22174.html

相關(guān)文章

  • n塞爾曲線bezierjavascript 實(shí)現(xiàn)解析

    摘要:最近學(xué)習(xí),看到曲線,所以補(bǔ)充了下知識,另外相關(guān)的數(shù)學(xué)定律都忘光了需要了解的前期需要了解相關(guān)的知識,可以看下維基百科什么是貝塞爾曲線什么是線性插值繪制本身只提供了二次和三次的繪制函數(shù),如果更高階級的怎么辦呢要對起進(jìn)行降階拆分。 最近學(xué)習(xí)canvas,看到bezier曲線,所以補(bǔ)充了下知識,另外相關(guān)的數(shù)學(xué)定律都忘光了~ 需要了解的 前期需要了解相關(guān)的知識,可以看下維基百科 什么是貝塞爾曲...

    EastWoodYang 評論0 收藏0
  • 如何理解并應(yīng)用塞爾曲線

    摘要:動(dòng)畫曲線的應(yīng)用了解了如何用貝塞爾曲線來指定動(dòng)畫曲線后,很多動(dòng)畫涉及到速度方面的效果就可以實(shí)現(xiàn)了,例如小車加速剎車,彈簧動(dòng)畫等速度軌跡都可以根據(jù)自己的需要來進(jìn)行定制。 貝塞爾曲線又叫貝茲曲線,在大學(xué)高數(shù)中一度讓我非常頭疼。前陣子練手寫動(dòng)畫的時(shí)候,發(fā)現(xiàn)貝塞爾曲線可以應(yīng)用于軌跡的繪制以及定義動(dòng)畫曲線。 本文就來探究一下,貝塞爾曲線到底是個(gè)什么樣的存在。 貝塞爾曲線原理 貝塞爾曲線由n個(gè)點(diǎn)來決...

    余學(xué)文 評論0 收藏0
  • 塞爾曲線算法之JS獲取點(diǎn)

    摘要:什么是貝塞爾曲線貝塞爾曲線,又稱貝茲曲線或貝濟(jì)埃曲線,是應(yīng)用于二維圖形應(yīng)用程序的數(shù)學(xué)曲線。這個(gè)是三階貝塞爾曲線,同理,綠點(diǎn)有個(gè),點(diǎn)與點(diǎn)之間都是按百分比運(yùn)動(dòng),最終得到一個(gè)小黑點(diǎn)。同理,還有四階貝塞爾。我們看看中階貝塞爾曲線上獲取點(diǎn)的效果的地址 什么是貝塞爾曲線? 貝塞爾曲線(Bézier curve),又稱貝茲曲線或貝濟(jì)埃曲線,是應(yīng)用于二維圖形應(yīng)用程序的數(shù)學(xué)曲線。 showImg(htt...

    SQC 評論0 收藏0
  • 【前端優(yōu)化】動(dòng)畫幾種實(shí)現(xiàn)方式總結(jié)和性能分析

    摘要:備注沒整理格式,抱歉動(dòng)畫實(shí)現(xiàn)的幾種方式性能排序?qū)崿F(xiàn)方式自身調(diào)用調(diào)用的定時(shí)器值推薦最小使用的原因即每秒幀為什么倒計(jì)時(shí)動(dòng)畫一定要用而避免使用兩者區(qū)別及引發(fā)的線程討論線程討論為什么單線程是的一大特性。 備注:沒整理格式,抱歉 動(dòng)畫實(shí)現(xiàn)的幾種方式:性能排序js < requestAnimationFrame 3->4->2. 那么在來看你這段代碼。 var t = true; window...

    IamDLY 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<