2014-09-25 2 views
0

Мне нужно нарисовать дугу с начальной точкой, радиусом и конечной точкой.Нарисуйте начальную точку дуги, радиус и конечную точку в JavaScript Холст

Я использую функцию HTML canvas arc (x, y, radius, startAngle, endAngle, против часовой стрелки) в JavaScript.

context.arc (х, у, радиус, StartAngle, endAngle, против часовой стрелки)

Есть:

var initialPoint = { x: 20, y: 40 }; 
var radius = 40; 
var finalPoint = { x: 180, y: 40 }; 

Ожидаемые результаты:

samples

пожалуйста, некоторые помогают

+0

'context.arc' никогда не нарисовать дугу, соединяющую initialPoint & finalPoint, если желаемый радиус 40. Дуга, проходящая через эти 2 пункта 80. Помните, что' context.arc' ** всегда будет нарисуйте частичный круг **, чтобы кривая не могла быть «согнута», чтобы растянуться между этими двумя точками. Как было предложено в предыдущем вопросе на эту тему ... используйте 'context.quadraticCurveTo', чтобы« согнуть »кривую между двумя точками. ;-) – markE

ответ

2

Вы должны сделать немного математик, чтобы найти центр окружности, который соответствует вашему 3 ограничению:
• пересекается с initialPoints
• пересекается с finalPoint
• обеспечил радиус

Обратите внимание, что не может быть никакого результата: если точки находятся дальше от дважды радиус друг от друга, ни один круг не может совпадать.
Если очки < 2 * радиус, у нас есть два. Фактически, я не знаю, как вы хотите, чтобы ваш пользователь выбирал.

Математика использует несколько свойств:
• центр кругов находится на линии, перпендикулярной p1, p2.
• pm, средняя точка (p1, p2) также является средней точкой (c1, c2).
• треугольники (p1, pm, c1) и (p1, pm, c2) имеют угол 90 ° в pm (называемый «треугольник прямоугольником» на французском, donno на английском языке).

Вот скриншот с двумя возможными дугами в зеленый/красный:

enter image description here

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

var initialPoint = { x: 100, y: 160 }; 
var radius = 90; 
var finalPoint = { x: 240, y: 190 }; 

var centers = findCenters(radius,initialPoint, finalPoint); 

функции ядра:

// 
function findCenters(r, p1, p2) { 
    // pm is middle point of (p1, p2) 
    var pm = { x : 0.5 * (p1.x + p2.x) , y: 0.5*(p1.y+p2.y) } ; 
    drawPoint(pm, 'PM (middle)'); 
    // compute leading vector of the perpendicular to p1 p2 == C1C2 line 
    var perpABdx= - (p2.y - p1.y); 
    var perpABdy = p2.x - p1.x; 
    // normalize vector 
    var norm = Math.sqrt(sq(perpABdx) + sq(perpABdy)); 
    perpABdx/=norm; 
    perpABdy/=norm; 
    // compute distance from pm to p1 
    var dpmp1 = Math.sqrt(sq(pm.x-p1.x) + sq(pm.y-p1.y)); 
    // sin of the angle between { circle center, middle , p1 } 
    var sin = dpmp1/r ; 
    // is such a circle possible ? 
    if (sin<-1 || sin >1) return null; // no, return null 
    // yes, compute the two centers 
    var cos = Math.sqrt(1-sq(sin)); // build cos out of sin 
    var d = r*cos; 
    var res1 = { x : pm.x + perpABdx*d, y: pm.y + perpABdy*d }; 
    var res2 = { x : pm.x - perpABdx*d, y: pm.y - perpABdy*d }; 
    return { c1 : res1, c2 : res2} ; 
} 

утилиты:

function sq(x) { return x*x ; } 

function drawPoint(p, name) { 
    ctx.fillRect(p.x - 1,p.y - 1,2, 2); 
    ctx.textAlign = 'center'; 
    ctx.fillText(name, p.x, p.y+10); 
} 

function drawCircle(c, r) { 
    ctx.beginPath(); 
    ctx.arc(c.x, c.y, r, 0, 6.28); 
    ctx.strokeStyle='#000'; 
    ctx.stroke(); 
} 

function drawCircleArc(c, r, p1, p2, col) { 
    var ang1 = Math.atan2(p1.y-c.y, p1.x-c.x); 
    var ang2 = Math.atan2(p2.y-c.y, p2.x-c.x); 
    ctx.beginPath(); 
    var clockwise = (ang1 > ang2); 
    ctx.arc(c.x, c.y, r, ang1, ang2, clockwise); 
    ctx.strokeStyle=col; 
    ctx.stroke(); 
} 

Edit:

Здесь скрипку с помощью «» стороны, логическая переменная, которая гласит, какая сторона дуги мы должны выбрать.

http://jsbin.com/jutidigepeta/3/edit

+0

Добро пожаловать.Мое псевдо GameAlchemist, я уверен, вы можете потратить время, необходимое для ввода всего. О вашем вопросе, если я думаю, хорошо, это знать, какую сторону дуги рисовать, в этом случае вы можете: 1) дать третьему пользователю указать ту часть пространства, где должна быть дуга. 2) считают, что дуга всегда должна быть слева от p1p2. Rq, что в этом случае имеет место порядок (p1, p2). – GameAlchemist

+0

mmm second подумал, что я думаю, что логический параметр влево/вправо - лучший вариант. Ввод - P1, P2, R, сторона. Просто измените мой код, в drawCircleArc, var по часовой стрелке = на стороне; и использовать только c1, первый центр вычисленных кругов. См. Мое редактирование. – GameAlchemist

Смежные вопросы