Arunkumar Vasudevan
Arunkumar Vasudevan

Reputation: 5330

draw angle arc inside the shape at any point in javascript

i have a four points. its draggable. at any point i click 'draw' button i want to show the angles. i tried but it will draw arc outside the shape sometimes. but i want to draw the arc inside the shape at any point.

for Example:

enter image description here

The above arc i want to draw inside the shape

$(document).ready(function(){
    var c=document.getElementById('canvas');
    var ctx=c.getContext("2d");
    var a1=parseInt($("#p1").css("left"))-5;
    var a2=parseInt($("#p1").css("top"))-5;
    var b1=parseInt($("#p2").css("left"))-5;
    var b2=parseInt($("#p2").css("top"))-5;
    var c1=parseInt($("#p3").css("left"))-5;
    var c2=parseInt($("#p3").css("top"))-5;
    var d1=parseInt($("#p4").css("left"))-5;
    var d2=parseInt($("#p4").css("top"))-5;


    ctx.beginPath();
    ctx.moveTo(a1,a2)
    ctx.lineTo(b1,b2)
    ctx.lineTo(c1,c2)
    ctx.lineTo(d1,d2)
    ctx.lineTo(a1,a2)
    ctx.fillStyle='#E6E0EC';
    ctx.fill();
    ctx.strokeStyle="#604A7B";
    ctx.lineWidth="3"
    ctx.stroke();
    ctx.closePath();
    $("#p1,#p2,#p3,#p4").draggable({
    drag:function(){

    a1=parseInt($("#p1").css("left"))-5;
    a2=parseInt($("#p1").css("top"))-5;
    b1=parseInt($("#p2").css("left"))-5;
    b2=parseInt($("#p2").css("top"))-5;
    c1=parseInt($("#p3").css("left"))-5;
    c2=parseInt($("#p3").css("top"))-5;
    d1=parseInt($("#p4").css("left"))-5;
    d2=parseInt($("#p4").css("top"))-5;

    ctx.clearRect(0,0,500,500);
    ctx.beginPath();


    ctx.moveTo(a1,a2)
    ctx.lineTo(b1,b2)
    ctx.lineTo(c1,c2)
    ctx.lineTo(d1,d2)
    ctx.lineTo(a1,a2)
    ctx.fillStyle='#E6E0EC';
    ctx.fill();
    ctx.strokeStyle="#604A7B";
    ctx.lineWidth="3"
    ctx.stroke();
    ctx.closePath();
                   }

    });

$("#draw").click(function(){

var dx1 = a1 - b1;
var dy1 = a2 - b2;
var dx2 = c1 - b1;
var dy2 = c2 - b2;
var ax1 = Math.atan2(dy1, dx1);
var ax2 = Math.atan2(dy2, dx2);
var a = parseInt((ax2 - ax1) * 180 / Math.PI + 360) % 360;
ctx.save();
ctx.beginPath();
ctx.moveTo(b1, b2);
ctx.arc(b1, b2, 20, ax1, ax2);
ctx.closePath();
ctx.fillStyle = "red";
ctx.globalAlpha = 0.25;
ctx.fill();
ctx.restore();
ctx.fillStyle = "black";
ctx.fillText(a, b1 + 15, b2);

});


    });

please lookout the fiddle:http://jsfiddle.net/BKK5z/1/

Upvotes: 0

Views: 476

Answers (1)

user1693593
user1693593

Reputation:

You can determine if the angle is drawn on the outside by using an angle mid-way on the resulting arc. For simplicity you can do something like this:

/// detect if arc is inside or outside polygon:
var aa = ax1 + 0.25;             /// for demo, replace with more accurate math
var x = b1 + 10 * Math.cos(aa);  /// some radius
var y = b2 + 10 * Math.sin(aa);

/// test point
var isInside = ctx.isPointInPath(x, y);

The value from isInside will be either true or false and we can use that directly with the arc method as the last argument which is the anti-clockwise flag:

ctx.arc(b1, b2, 20, ax1, ax2, !isInside);

Modified fiddle here

Notes:

The "angle detection" above is very simplified and won't work on steep angles.

Therefor you need to replace it with something that calculates the average between the two angles so you use that mid-way angle as basis for testing the points (or find a value that just barely makes it on the inside/outside).

The radius may also need adjustment if the rectangle section gets very tiny. Point being (no pun intended) that you need to do a test to see if you are inside or outside the polygon.

Upvotes: 1

Related Questions