Domanda

Ciao a tutti -

Sto utilizzando punti di ancoraggio e punti di controllo per creare una forma utilizzando curveTo.Funziona tutto bene, ma non riesco a capire come far passare le mie linee attraverso il centro dei punti di controllo (punti blu) quando la linea non è diritta.

Ecco il mio codice per disegnare la forma:

           // clear old line and draw new / begin fill
        var g:Graphics = graphics;
        g.clear();
        g.lineStyle(2, 0, 1);
        g.beginFill(0x0099FF,.1);

        //move to starting anchor point
        var startX:Number = anchorPoints[0].x;
        var startY:Number = anchorPoints[0].y;
        g.moveTo(startX, startY);

        // Connect the dots
        var numAnchors:Number = anchorPoints.length;
        for (var i:Number=1; i<numAnchors; i++) {

            // curve to next anchor through control
            g.curveTo(controlPoints[i].x,controlPoints[i].y, anchorPoints[i].x, anchorPoints[i].y);

        }
        // Close the loop
        g.curveTo(controlPoints[0].x,controlPoints[0].y,startX,startY);

E la forma che sto disegnando come riferimento:

Come posso modificare il mio codice in modo che le linee passino direttamente attraverso i punti di controllo blu?

Grazie in anticipo!

B

È stato utile?

Soluzione

Progetto di esempio Codice sorgente

Se non sei interessato a come viene derivato, passa alla sezione delle risposte.

Informazioni di base


Curve di Bezier sono interessanti e divertenti con cui lavorare. Questa animazione mostra come viene disegnata la curva quadratica tra i due punti di ancoraggio (P0 e P2) nel tempo rispetto al punto di controllo (P1).

Quello che devi fare, invece di disegnare il punto di controllo (P1), è disegnare il punto sulla curva a t=0,5:

Point at t=0.5
(fonte: whilenotnull.com)

Fortunatamente questo è facile da fare con l'equazione fornita nella pagina Wikipedia: http://en.wikipedia.org/wiki/Bezier_Curve#Quadratic_B.C3.A9zier_curves

Ecco la formula in Actionscript:

public function calculatePoint(p0:Point, p1:Point, p2:Point, t:Number):Point
{
    var p:Point = new Point(calculateTerm(p0.x, p1.x, p2.x, t), calculateTerm(p0.y, p1.y, p2.y, t));
    return p;
}

public function calculateTerm(p0:Number, p1:Number, p2:Number, t:Number):Number
{
    var negT:Number = 1 - t;

    var a0:Number = Math.pow(negT, 2) * p0;
    var a1:Number = 2 * negT * t * p1;
    var a2:Number = Math.pow(t, 2) * p2;

    var pos:Number = a0 + a1 + a2;
    return pos;
}

Quindi se colleghi i tre punti: var t0:Point = calculatePoint(p0, p1, p2, 0.5); otterrai il punto sulla curva in cui vuoi disegnare il tuo "punto di controllo".


Risposta

Ora possiamo scrivere una funzione che presuppone che il secondo parametro sia un punto sulla curva e determinare le coordinate del punto di controllo:

public function derivePoint(p0:Point, b1:Point, p2:Point, t:Number = 0.5):Point
{
    var p:Point = new Point(deriveTerm(p0.x, b1.x, p2.x, t), deriveTerm(p0.y, b1.y, p2.y, t));
    return p;
}

public function deriveTerm(p0:Number, bt:Number, p2:Number, t:Number):Number
{
    var negT:Number = 1 - t;

    var a0:Number = Math.pow(negT, 2) * p0;
    var a1:Number = 2 * negT * t;
    var a2:Number = Math.pow(t, 2) * p2;

    var p1:Number = (bt - a0 - a2) / a1;
    return p1;
}

Da questo ho aggiornato il tuo snippet di codice per (si spera) disegnare la curva attraverso i tuoi "punti di controllo":

// clear old line and draw new / begin fill
var g:Graphics = graphics;
g.clear();
g.lineStyle(2, 0, 1);
g.beginFill(0x0099FF,.1);

//move to starting anchor point
var startX:Number = anchorPoints[0].x;
var startY:Number = anchorPoints[0].y;
g.moveTo(startX, startY);

// Connect the dots
var p0:Point = new Point(startX, startY);
var p2:Point;

var numAnchors:Number = anchorPoints.length;
for (var i:Number=1; i<numAnchors; i++) {

    p2 = new Point(anchorPoints[i].x, anchorPoints[i].y);

    // curve to next anchor through control
    var b1:Point = new Point(controlPoints[i].x,controlPoints[i].y);
    var p1:Point = derivePoint(p0, b1, p2);

    g.curveTo(p1.x, p1.y, p2.x, p2.y);

    p0 = p2;

}
// Close the loop
g.curveTo(controlPoints[0].x,controlPoints[0].y,startX,startY);

Progetto di esempio Codice sorgente

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top