給定一個X座標:如何獲得2個垂直堆疊貝塞爾曲線的Y座標。
我能想到2種方式,都使用「蠻力」。
第一種方法:檢查像素:
- 畫上一個單獨的畫布上的兩個貝濟耶。
- 使用context.getImageData獲得通過時,在您需要的X每個垂直的Y像素座標
- 如果你找到一個非透明像素,您協調X.
- 迭代在畫布上所有的垂直像素陣列「VE打貝塞爾(和它的Y)
- 迭代從上到下,直到你找到頂級的貝塞爾Y.從底部
- 迭代頂部,直到找到底部貝塞爾Y.

下面是第一方法代碼和小提琴:http://jsfiddle.net/m1erickson/uRDYf/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
#canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
// draw a top bezier
ctx.beginPath();
ctx.moveTo(50,50);
ctx.bezierCurveTo(125,0,150,100,250,75);
ctx.lineWidth=3;
ctx.strokeStyle="black";
ctx.stroke();
// draw a bottom bezier
ctx.beginPath();
ctx.moveTo(50,150);
ctx.bezierCurveTo(125,0,150,100,250,175);
ctx.lineWidth=3;
ctx.strokeStyle="blue";
ctx.stroke();
// get an array of all the pixels in the canvas
var x=100; // put your X coordinate value here
var iData = ctx.getImageData(x,0,1,canvas.height);
var data = iData.data;
var w=canvas.width;
var h=canvas.height;
var theY1=-999; // your top result
var theY2=-999; // your bottom result
// iterate through each Y at your vertical X coordinate
// Examine the opacity value at the XY
// if the pixel is not transparent, you have found your Y
for(var y=0; y<h; y++) {
if(data[y*4+3]>10){
theY1=y;
break;
}
}
// now iterate backwards to get the Y of the bottom curve
for(var y=0; y<h; y++) {
if(data[(h-y)*4+3]>10){
theY2=(h-y);
break;
}
}
// testing -- display the results
ctx.beginPath();
ctx.moveTo(x,0);
ctx.lineTo(x,h);
ctx.strokeStyle="lightgray";
ctx.stroke();
ctx.beginPath();
ctx.arc(x,theY1,4,Math.PI*2,false);
ctx.closePath();
ctx.arc(x,theY2,4,Math.PI*2,false);
ctx.closePath();
ctx.fillStyle="red";
ctx.fill();
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>
第二種方法:使用貝塞爾曲線式重複「猜測」的Y座標。
僅供參考,三次Bezier實際上確實有一個公式
// where ABCD are the control points and T is an interval along that curve
function CubicN(T, a,b,c,d) {
var t2 = T*T;
var t3 = t2*T;
return a + (-a * 3 + T * (3 * a - a * T)) * T
+ (3 * b + T * (-6 * b + b * 3 * T)) * T
+ (c * 3 - c * 3 * T) * t2
+ d * t3;
}
你可以沿着這個公式是這樣計算XY點:
// cubic bezier T is 0-1
// When T==0.00, you are at the beginning of the Curve
// When T==1.00, you are at the ending of the Curve
function getCubicBezierXYatT(startPt,controlPt1,controlPt2,endPt,T){
var x=CubicN(T,startPt.x,controlPt1.x,controlPt2.x,endPt.x);
var y=CubicN(T,startPt.y,controlPt1.y,controlPt2.y,endPt.y);
return({x:x,y:y});
}
所以第二個方法是重複「猜測「使用getCubicBezierXYatT沿曲線的T值。
當返回的X是你想要的X時,你也有你想要的Y.
我還沒有嘗試過,但這種SO後使用一種叫做牛頓迭代改進,以使其比隨機猜測更好:
Getting y from x co-ord for cubic bezier curve, fast Newton-Raphson method
你的問題是混亂的 - 至少對我來說:)你能發表你想要做什麼的形象嗎?或者也許重新提出你的問題。 – markE
添加相關的代碼,因此很難理解你在說什麼。 – Ani