2016-05-31 45 views
-1

可能會有人知道好JavaScript圖書館或畫布繪製的框架。將行轉換爲「矩形蛇」。帆布。 JavaScript

我有以下問題:

1)通過徒手畫一些線路(如油漆/ Photoshop的鉛筆)

2)需要轉換線爲 「矩形蛇」(建使用固定寬度的矩形)

看看截圖 enter image description here

什麼樣的升線圖書館會更好地用於這個問題? 可能是某種圖書館艾雷迪有這個功能?

我的意思是需要下列功能:

  • 線近似

  • 花鍵分離

  • 轉換加工生產線,以多邊形/形狀/對象

將是巨大的,如果有人會幫助我。謝謝!

+0

固定寬度,你的意思固定長度? –

+0

是的,我的意思是 – archik

回答

1

正如你在你的問題中所說的,你的觀點可以是由一組三次貝塞爾曲線組成的turned into a spline。提示:在計算剩餘(較少)點的樣條之前,您可能需要simplify the point-set

以下介紹如何計算沿立方貝塞爾曲線的一組矩形多邊形。

旁註:多邊形必須是矩形,因爲不可能沿着彎曲路徑創建一組側邊連接的矩形。

enter image description here

  1. 計算一組沿曲線的點。
  2. 使用#1中的點,計算每個點的切線角度。
  3. 使用點數&角度,計算從每個點向兩個方向向外延伸的垂直線。
  4. 使用垂直線的端點來構建一組多邊形。每個新的多邊形都是由當前的垂直端點構建的。

這裏被註釋的代碼和一個演示:

// canvas related variables 
 
var canvas=document.getElementById("canvas"); 
 
var ctx=canvas.getContext("2d"); 
 

 
// variables defining a cubic bezier curve 
 
var PI=Math.PI; 
 
var PI2=PI*2; 
 
var s={x:20,y:30}; 
 
var c1={x:300,y:40}; 
 
var c2={x:40,y:150}; 
 
var e={x:370,y:170}; 
 

 
// an array of points plotted along the bezier curve 
 
var points=[]; 
 
// an array of polygons along the bezier curve 
 
var polys=[]; 
 

 
// plot some points & tangent angles along the curve 
 
for(var t=0;t<=100;t+=4){ 
 

 
    var T=t/100; 
 

 
    // plot a point on the curve 
 
    var pos=getCubicBezierXYatT(s,c1,c2,e,T); 
 

 
    // calculate the tangent angle of the curve at that point 
 
    var tx = bezierTangent(s.x,c1.x,c2.x,e.x,T); 
 
    var ty = bezierTangent(s.y,c1.y,c2.y,e.y,T); 
 
    var a = Math.atan2(ty, tx)-PI/2; 
 

 
    // save the x/y position of the point and the tangent angle 
 
    points.push({ 
 
    x:pos.x, 
 
    y:pos.y, 
 
    angle:a 
 
    });   
 
} 
 

 
// create polygons that extend on either side of the 
 
//  original points set 
 
for(var i=1;i<points.length;i++){ 
 
    var p0=points[i-1]; 
 
    var p1=points[i]; 
 
    polys.push({ 
 
    x0:p0.x+20*Math.cos(p0.angle), 
 
    y0:p0.y+20*Math.sin(p0.angle), 
 
    x1:p1.x+20*Math.cos(p1.angle), 
 
    y1:p1.y+20*Math.sin(p1.angle), 
 
    x2:p1.x+20*Math.cos(p1.angle-PI), 
 
    y2:p1.y+20*Math.sin(p1.angle-PI),     
 
    x3:p0.x+20*Math.cos(p0.angle-PI), 
 
    y3:p0.y+20*Math.sin(p0.angle-PI), 
 
    }); 
 
} 
 

 
// draw the polygons 
 
for(var i=0;i<polys.length;i++){ 
 
    var r=polys[i]; 
 
    ctx.beginPath(); 
 
    ctx.moveTo(r.x0,r.y0); 
 
    ctx.lineTo(r.x1,r.y1); 
 
    ctx.lineTo(r.x2,r.y2); 
 
    ctx.lineTo(r.x3,r.y3); 
 
    ctx.closePath(); 
 
    ctx.fillStyle=randomColor(); 
 
    ctx.fill(); 
 
    ctx.stroke(); 
 
} 
 

 
// draw the bezier curve points 
 
ctx.beginPath(); 
 
ctx.moveTo(points[0].x,points[0].y); 
 
for(var i=0;i<points.length;i++){ 
 
    ctx.lineTo(points[i].x,points[i].y); 
 
} 
 
ctx.lineWidth=3; 
 
ctx.strokeStyle='red'; 
 
ctx.stroke(); 
 

 
function randomColor(){ 
 
    return('#'+Math.floor(Math.random()*16777215).toString(16)); 
 
} 
 

 

 
////////////////////////////////////////// 
 
// helper functions 
 
////////////////////////////////////////// 
 

 
// calculate one XY point along Cubic Bezier at interval T 
 
// (where T==0.00 at the start of the curve and T==1.00 at the end) 
 
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}); 
 
} 
 

 
// cubic helper formula at T distance 
 
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; 
 
} 
 

 
// calculate the tangent angle at interval T on the curve 
 
function bezierTangent(a, b, c, d, t) { 
 
    return (3 * t * t * (-a + 3 * b - 3 * c + d) + 6 * t * (a - 2 * b + c) + 3 * (-a + b)); 
 
};
body{ background-color:white; padding:10px; } 
 
#canvas{border:1px solid red; margin:0 auto; }
<h4>"Rectangular-ish" polygons along the red cubic bezier curve.</h4> 
 
<canvas id="canvas" width=400 height=300></canvas>

均勻寬度的多邊形:

同樣,因爲它們是矩形肥胖型多邊形, 你會 無法獲得精確一致的寬度。獲得半統一寬度:

  • 計算曲線上的許多點(可能爲1000+)。
  • 使用距離公式來降低1000+點設置爲點集與沿着曲線均勻的距離:所述封閉曲線段var distance=Math.sqrt((pt1.x-pt0.x)*(pt1.x-pt0.x) + (pt1.y-pt0.y)*(pt1.y-pt0.y))