2016-02-12 35 views
2

我一直在嘗試使用bezierCurveToHTML5使用bezierCurveTo

在下面找到

<canvas id="thisCan" width="0px" height="0px" style="border:1px solid #d3d3d3;"> 
Your browser does not support the HTML5 canvas tag. 
</canvas> 

<script> 
(function() { 
var 
// Obtain a reference to the canvas element 
// using its id. 
htmlCanvas = document.getElementById('thisCan'), 
    // Obtain a graphics context on the 
    // canvas element for drawing. 
    ctx = htmlCanvas.getContext('2d'); 

var width = 0; 
var height = 0; 

// Start listening to resize events and 
// draw canvas. 
initialize(); 

function initialize() 
{ 
    // Register an event listener to 
    // call the resizeCanvas() function each time 
    // the window is resized. 
    window.addEventListener('resize', resizeCanvas, false); 
    // Draw canvas border for the first time. 
    resizeCanvas(); 
} 

// Display custom canvas. 
// In this case it's a blue, 5 pixel border that 
// resizes along with the browser window. 
function redraw() 
{ 
    ctx.beginPath(); 

    ctx.moveTo(width/2, 0); 
    ctx.bezierCurveTo(150, 119, 186, 121, 66, 185); 

    ctx.moveTo(width/2 + width * 0.08 , 0); 
    ctx.bezierCurveTo(344, 119, 344, 121, 504, 185); 

    ctx.stroke(); 
} 

// Runs each time the DOM window resize event fires. 
// Resets the canvas dimensions to match window, 
// then draws the new borders accordingly. 
function resizeCanvas() 
{ 
    var contentElement = document.getElementsByClassName("content-box post")[0] 
    width = htmlCanvas.width = (contentElement.clientWidth * 0.75) 
    height = htmlCanvas.height = (contentElement.offsetWidth*0.75 * 0.5); 

    redraw(); 
} 

})(); 
</script> 

我打算畫許多曲線之間以及代碼繪製gaussin樣功能繪製高斯函數。 但是,如何根據widthheight變量使參數爲

我需要使用寬度和高度參數指定控制點,以便它變成窗口大小不變。

有沒有辦法?

+0

對不起,你能展示完整的代碼並描述你想要的嗎? P.S.不要使用全局變量=)只需發送'width'和'height'到'redraw()'和_Use'requestAnimationFrame()',Luke_代替'resize'(更多地介紹https://developer.mozilla.org/en-US/docs/Web/Events/resize) –

+0

@RudolfManusadzhyan,感謝您分享寶貴的知識。今天只有我開始學習javascript,所以我會記住 - no_globals!用'requestAnimationFrame()',我不尋找動畫。我只需要確保在調整窗口大小時我的圖形不會被忽視。所以我認爲resize()更合適,糾正我,如果我錯了。順便說一句,我解決了這個問題 – Adorn

+0

問題:爲什麼?如果要繪製高斯曲線,只需對曲線進行取樣並通過連接點來繪製它(字面上,通過貫穿點陣列和從一點到另一線的點)。使用貝塞爾曲線在這裏沒有太多意義。 –

回答

1

不要使用貝塞爾曲線,如果你想要一個指數曲線,它們是不同的功能。相反,剛剛繪製你的實際需要的功能,喜歡的東西http://jsbin.com/nubutodosu/edit?js,output,在那裏你定義一個高斯對象:

// Gaussian distribution generator 

var Gaussian = function(mean, std) { 
    this.mean = mean; 
    this.std = std; 
    this.a = 1/Math.sqrt(2*Math.PI); 
}; 

Gaussian.prototype = { 
    addStd: function(v) { 
    this.std += v; 
    }, 

    get: function(x) { 
    var f = this.a/this.std; 
    var p = -1/2; 
    var c = (x-this.mean)/this.std; 
    c *= c; 
    p *= c; 
    return f * Math.pow(Math.E, p); 
    }, 

    generateValues: function(start, end) { 
    var LUT = []; 
    var step = (Math.abs(start)+Math.abs(end))/100; 
    for(var i=start; i<end; i+=step) { 
     LUT.push(this.get(i)); 
    } 
    return LUT; 
    } 
}; 

然後你可以給一個抽獎程序,以便它可以繪製自己在您需要的時間間隔:

... 
    draw: function(ctx) { 
    var points = this.generateValues(-10,10); 
    var len = points.length; 
    ctx.strokeStyle = "black"; 
    ctx.beginPath(); 
    var p0 = points[0]; 
    ctx.moveTo(0, height - (height*p0)); 
    points.forEach(function(p,i) { 
     if(i===0) { 
     return; 
     } 
     ctx.lineTo(width * i/len, height - (height*p)); 
     p0 = p; 
    }); 
    ctx.stroke(); 
    } 
... 

因此,你在間隔中建立你的值的數組,然後通過「連接點」在畫布上繪製它們。

+0

是的,你的解決方案很有意義。 – Adorn

-1

我設法解決它。

具體而言,我正在尋找半高斯曲線。

我設法弄清楚guassian function對於bezier curves有一個非常特殊的屬性。這可能是初級的,但我無法在谷歌上找到它。所以這可能是有益的發現。

如果三次貝塞爾曲線的每個控制點位於「平行於X軸並通過起始點/終點的線上」,則生成的曲線將爲半高斯形狀。

例如

enter image description here

在此發現的頂部,我寫了下面的代碼:

<canvas id="thisCan" width="0px" height="0px"> 
Your browser does not support the HTML5 canvas tag. 
</canvas> 

<script> 
(function() { 
var 
// Obtain a reference to the canvas element 
// using its id. 
htmlCanvas = document.getElementById('thisCan'), 
    // Obtain a graphics context on the 
    // canvas element for drawing. 
    ctx = htmlCanvas.getContext('2d'); 

// Start listening to resize events and 
// draw canvas. 
initialize(); 

function initialize() 
{ 
    // Register an event listener to 
    // call the resizeCanvas() function each time 
    // the window is resized. 
    window.addEventListener('resize', resizeCanvas, false); 
    // Draw canvas border for the first time. 
    resizeCanvas(); 
} 

// Display custom canvas. 
// In this case it's a blue, 5 pixel border that 
// resizes along with the browser window. 
function redraw(width, height) 
{ 
    var start = width/2; 
    var margin = width * 0.01; 
    var height = (width/3) - (margin * 4); 
    var end_step = width/4 

    ctx.beginPath(); 

    ctx.moveTo(start - margin, 0); 
    ctx.bezierCurveTo((start - height/3), 0 , (start - height/3), height , end_step*1, height); 

    ctx.moveTo(start + margin, 0); 
    ctx.bezierCurveTo((start + height/3), 0 , (start + height/3), height , end_step*3, height); 

    ctx.moveTo(start - margin, 0); 
    ctx.bezierCurveTo((start - height*0.33), 0 , (start - height*0.16), height , end_step*1.5, height); 

    ctx.moveTo(start + margin, 0); 
    ctx.bezierCurveTo((start + height*0.33), 0 , (start + height*0.16), height , end_step*2.5, height); 

    ctx.moveTo(start, 0); 
    ctx.bezierCurveTo((start), 0 , (start), height , end_step*2, height); 

    ctx.stroke(); 
} 

// Runs each time the DOM window resize event fires. 
// Resets the canvas dimensions to match window, 
// then draws the new borders accordingly. 
function resizeCanvas() 
{ 
    var width = 0; 
    var height = 0; 

    var contentElement = document.getElementsByClassName("content-box post")[0] 
    width = htmlCanvas.width = (contentElement.clientWidth * 0.85) 
    height = htmlCanvas.height = (contentElement.offsetWidth*0.85 * 0.33); 

    redraw(width, height); 
} 

})(); 
</script> 

和輸出:

enter image description here

+1

不,它不會。高斯函數從零負無窮到零無窮。對於任何實數值「x」它永遠不會評估爲零。而且,由於高斯運行整條實線,「半」高斯仍然是無限長的,所以用它來表示你所展示的曲線是使用錯誤的條件。你只是以相對較高的平均值標準差顯示曲線。它看起來非常像你實際想要繪製的是一個[sigmoid](https://en.wikipedia.org/wiki/Sigmoid_function),它的運行從0到1. –