2016-05-31 9 views
-1

Kann jemand gut wissen JavaScript Bibliothek oder Framework für Leinwand zeichnen.Konvertieren Sie die Zeile in "Rechteck Schlange". Segeltuch. JavaScript

ich folgendes Problem habe:

1) eine Linie über freihändig zeichnen (wie Paint/Photoshop Bleistift)

2) konvertiert Linie in "Rechteck Schlange" (build a Linie Rechtecke mit fester Breite)

Blick auf Screenshot enter image description here

Welche Art von l mit ibrary wird besser für dieses Problem verwendet werden? Kann eine Art von Bibliothek alredy diese Funktionalität haben?

meine ich folgende Funktionalität benötigen:

  • Approximationscharakteristika

  • Spline Trennung

  • Umwandlung Linie Polygone/Formen/Objekte

wird groß sein, wenn jemand wird mir helfen. Vielen Dank!

+0

mit fester Breite, haben Sie feste Länge des umschlossenen Kurvensegmentes das? –

+0

Ja, das meine ich – archik

Antwort

1

Wie Sie in Ihrer Frage sagen, können Ihre Punkte turned into a spline bestehend aus einer Reihe von kubischen Bezier-Kurven sein. Tipp: Sie könnten simplify the point-set vor dem Berechnen der Spline der verbleibenden (weniger) Punkte.

So berechnen Sie einen Satz rechteckiger Polygone entlang einer kubischen Bezier-Kurve.

Hinweis: Die Polygone müssen rechteckig sein, da es nicht möglich ist, einen Satz Seitenrechtecke entlang eines gekrümmten Pfads zu erstellen.

enter image description here

  1. eine Menge von Punkten entlang der Kurve berechnen.
  2. Mit den Punkten in # 1 den Tangentenwinkel für jeden der Punkte berechnen.
  3. Mit den Punkten & Winkel berechnen Sie senkrechte Linien, die sich von jedem Punkt in beide Richtungen nach außen erstrecken.
  4. Verwenden Sie die Endpunkte der senkrechten Linien, um eine Reihe von Polygonen zu erstellen. Jedes neue Polygon wird aus den aktuellen senkrechten Endpunkten & aufgebaut.

ist hier Code und eine Demo kommentierten:

// 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>

einheitliche Breite Polygonen:

Wiederum weil sie rechteck Ish Polygone , Du wirst nicht in der Lage sein, genau gleichförmige Breiten zu erhalten. Um halbgleiche Breiten zu erhalten:

  • Berechnen Sie viele Punkte entlang der Kurve (vielleicht 1000+).
  • den Abstand Formel des 1000+ Punkt-Set zu einer Punkt-Set mit gleichmäßigen Abständen entlang der Kurve zu reduzieren: var distance=Math.sqrt((pt1.x-pt0.x)*(pt1.x-pt0.x) + (pt1.y-pt0.y)*(pt1.y-pt0.y))