用垂直装饰画一条线

时间:2014-12-24 10:42:19

标签: javascript math canvas geometry

我需要按以下方式画一条线:

Example

目前,它只会在代码中绘制,无需用户输入。

我的问题是,如果我逐点绘制,如何将垂线绘制成一条直线? (显然,情况就是如此,因为使用贝塞尔曲线绘制不会让我有可能以某种方式影响绘图)。

我找到的最接近的答案可能是this one,但是我无法反转方程式来推导C.而且所提到的装饰没有长度,所以我认为这不会像我想的那样有效它来。

2 个答案:

答案 0 :(得分:5)

找到与另一个垂直的线段非常容易 假设我们有A点,B点 计算向量AB。
将其标准化以计算NAB(=='相同'向量,但长度为1)。
然后,如果向量具有(x,y)作为坐标,则其法向量具有(-y,x)作为坐标,因此 你可以轻松拥有PNAB(PNAB =垂直法线向量到AB)。

// vector AB
var ABx =  B.x - A.x ;
var ABy =  B.y - A.y ;
var ABLength = Math.sqrt( ABx*ABx + ABy*ABy );
// normalized vector AB
var NABx = ABx / ABLength;
var NABy = ABy / ABLength;
// Perpendicular + normalized vector.
var PNABx = -NABy ;
var PNABy =  NABx ;

最后一步是计算D,即距离为A的点:只需将l * PNAB添加到A:

// compute D = A + l * PNAB
var Dx = A.x + l* PNAB.x;
var Dy = A.y + l *PNAB.y;

更新了JSBIN:

http://jsbin.com/bojozibuvu/1/edit?js,output

编辑: 第二步是在常规距离画出装饰品,因为它是圣诞节的时候,我会怎样做:

http://jsbin.com/gavebucadu/1/edit?js,console,output

function drawDecoratedSegment(A, B, l, runningLength) {
    // vector AB
    var ABx = B.x - A.x;
    var ABy = B.y - A.y;
    var ABLength = Math.sqrt(ABx * ABx + ABy * ABy);
    // normalized vector AB
    var NABx = ABx / ABLength;
    var NABy = ABy / ABLength;
    // Perpendicular + normalized vector.
    var PNAB = {  x: -NABy,  y: NABx    };
    // 
    var C = { x: 0, y: 0    };
    var D = { x: 0, y: 0    };
    //
    drawSegment(A, B);
    // end length of drawn segment
    var endLength = runningLength + ABLength;
    // while we can draw a decoration on this line
    while (lastDecorationPos + decorationSpacing < endLength) {
        // compute relative position of decoration.
        var decRelPos = (lastDecorationPos + decorationSpacing) - runningLength;
        // compute C, the start point of decoration
        C.x = A.x + decRelPos * NABx;
        C.y = A.y + decRelPos * NABy;
        // compute D, the end point of decoration      
        D.x = C.x + l * PNAB.x;
        D.y = C.y + l * PNAB.y;
        // draw
        drawSegment(C, D);
        // iterate
        lastDecorationPos += decorationSpacing;
    }
    return ABLength;
}

答案 1 :(得分:1)

您需要的只是每个点的曲线方向(或折线线段),您想要垂直绘制。 如果点P0中的方向矢量是(dx,dy),那么垂直(左边)将具有方向矢量(-dy,dx)。要绘制垂直长度Len,请使用此伪代码:

Norm = Sqrt(dx*dx + dy*dy)   //use Math.Hypot if available
P1.X = P0.X - Len * dy / Norm
P1.Y = P0.Y + Len * dx / Norm

P.S。如果你知道方向角A,那么方向矢量

(dx, dy) = (Cos(A), Sin(A))

并且您不需要计算Norm,它等于1.0