ArcTo canvas confusion

So, I am again engaged in ring sectors, which are not my forte. I can use the method .arcon canvas very well, the problem arises because my arc is part of the path.

So for example:

 ctx.save();
 ctx.arc(centerX, centerY, radius, startAngle, endAngle, true);
 ctx.stroke();
 ctx.restore();

It works great. But now I need this as part of the path, so I have something like this:

 var pointArray = [...]; //this contains all four corner points of the annular sector
 ctx.save();
 ctx.moveTo(pointArray[0].x, pointArray[0].y);
 ctx.lineTo(pointArray[1].x, pointArray[1].y); //so that draws one of the flat ends
 ctx.arcTo(?, ?, pointArray[2].x pointArray[2].y, radius);

The tangent of the tangent coordinate is driving me crazy. Plus, I have a serious problem: http://www.dbp-consulting.com/tutorials/canvas/CanvasArcTo.html It sounds like an arc drawn with arcTo can never cover 180 degrees or more of a circle, and there will be times when my ring sector will be more than 180 degrees.

Thanks for helping improve stackoverflow geometric minds!

UPDATE , svg canvas inter-polarity , , script, !

 annularSector : (startAngle,endAngle,innerRadius,outerRadius) ->

    startAngle  = degreesToRadians startAngle+180
    endAngle    = degreesToRadians endAngle+180
    p           = [ 
        [ @centerX+innerRadius*Math.cos(startAngle),    @centerY+innerRadius*Math.sin(startAngle) ]
        [ @centerX+outerRadius*Math.cos(startAngle),    @centerY+outerRadius*Math.sin(startAngle) ]
        [ @centerX+outerRadius*Math.cos(endAngle),      @centerY+outerRadius*Math.sin(endAngle) ]
        [ @centerX+innerRadius*Math.cos(endAngle),      @centerY+innerRadius*Math.sin(endAngle) ] 
    ]
    angleDiff   = endAngle - startAngle
    largeArc    = (if (angleDiff % (Math.PI * 2)) > Math.PI then 1 else 0)

    if @isSVG

        commands    = []

        commands.push "M" + p[0].join()
        commands.push "L" + p[1].join()
        commands.push "A" + [ outerRadius, outerRadius ].join() + " 0 " + largeArc + " 1 " + p[2].join()
        commands.push "L" + p[3].join()
        commands.push "A" + [ innerRadius, innerRadius ].join() + " 0 " + largeArc + " 0 " + p[0].join()
        commands.push "z"

        return commands.join(" ")

    else

        @gaugeCTX.moveTo p[0][0], p[0][1]
        @gaugeCTX.lineTo p[1][0], p[1][1]
        #@gaugeCTX.arcTo 
        @gaugeCTX.arc @centerX, @centerY, outerRadius, startAngle, endAngle, false
        #@gaugeCTX.moveTo p[2][0], p[2][1]
        @gaugeCTX.lineTo p[3][0], p[3][1]
        @gaugeCTX.arc @centerX, @centerY, innerRadius, startAngle, endAngle, false          

enter image description here

        @gaugeCTX.moveTo p[0][0], p[0][1]
        @gaugeCTX.lineTo p[1][0], p[1][1]
        @gaugeCTX.arc @centerX, @centerY, outerRadius, startAngle, endAngle, false
        @gaugeCTX.lineTo p[3][0], p[3][1]
        @gaugeCTX.arc @centerX, @centerY, innerRadius, endAngle, startAngle, true #note that this arc is set to true and endAngle and startAngle are reversed!
+5
3

/ 100% ,

arcTo() /, arc().
(, , , firefox 12 ff3.6, ).

arc() , wiki, Math.PI , - , ( , - ) .
- : (((2 * Math.PI)/360) * 270) (= 3/4 )
: Radian/Unit ECMAscript!

, beginPath() closePath() ( ) ( ! () !

bezierCurveTo().

UPDATE ( TS): ( , ), , , : .

, beginPath() closePath() ( ).
, , - ( 0,0) translate(). , , : : (x.5, y.5).

"-" "temp-canvas". - ( mumbo jumbo) temp-canvas . , / . .

"" ( ) script, svg-, , ( ) javascript .

, !

2: .. /... ! , , .
javascript, .
, ( ) javascript, , canvas ( html).

.. svg-path to canvas translation-scripts.. ? , - / ( )..

3: . : , ".
( , ), (0,0), ( + 0.5px) !!!

+2

arcTo() ( roundedCorner()). , cx, cy, r, theta1, theta2:

http://www.purplefrog.com/~thoth/art/paisley/arcTo.html

, :

/**
   if code is "move" then we will do a moveTo x0,y0
   if code is "line" then we will do a lineTo x0,y0
   if code is anything else, we'll assume the cursor is already at x0,y0
*/
function otherArcTo(ctx, cx, cy, r, theta1, theta2, code)
{
    console.log([cx,cy,r,theta1, theta2, code])
    var x0 = cx + r*Math.cos(theta1)
    var y0 = cy + r*Math.sin(theta1)
    if (code=="move") {
        ctx.moveTo(x0,y0)
    } else if (code=="line") {
        ctx.lineTo(x0,y0)
    }

    var dTheta = theta2-theta1
    var nChunks = Math.ceil( Math.abs(dTheta) / (0.67*Math.PI) )
    if (nChunks <=1) {
        var theta3 = theta1 + dTheta/2
        var r3 = r/Math.cos(dTheta/2)
        var x1 = cx + r3*Math.cos(theta3)
        var y1 = cy + r3*Math.sin(theta3)
        var x2 = cx + r*Math.cos(theta2)
        var y2 = cy + r*Math.sin(theta2)
        ctx.arcTo(x1,y1,x2,y2, r)
    } else {
        for (var i=0; i<nChunks; i++) {
            var code2 = null
            if (i==0)
                code2 = code
            otherArcTo(ctx, cx, cy, r,
                       theta1 + dTheta*i/nChunks,
                       theta1 + dTheta*(i+1)/nChunks, code2)
        }
    }
}
+2

. , .

, arcTo(). () , / x y .

function calculateArcPoints(radius, rotation, sectionAngle) {
    var halfSectionAngle = sectionAngle / 2;

    return {
        control: {
            x: Math.cos(rotation) * radius / Math.cos(halfSectionAngle),
            y: -1 * Math.sin(rotation) * radius / Math.cos(halfSectionAngle)
        },
        start: {
            x: Math.cos(rotation - halfSectionAngle) * radius,
            y: -1 * Math.sin(rotation - halfSectionAngle) * radius
        },
        end: {
            x: Math.cos(rotation + halfSectionAngle) * radius,
            y: -1 * Math.sin(rotation + halfSectionAngle) * radius
        }
    };
}

KineticJS SVG script, . jsFiddle. , , . , , , .

. : http://www.dbp-consulting.com/tutorials/canvas/CanvasArcTo.html , , arcTo, 180 180 .

arcTo(). 180 . >= 180 & deg; , arcTo(). ( ) .

+1

All Articles