2016-03-02 9 views
1

Учитывая следующую информацию:Draw сегмент круга на SVG

  • белая точка является центром окружности.
  • синий, зеленый точки являются точками на границе круга.
  • ориентации: по часовой стрелке, против часовой стрелки

Используя любую точку (синий, зеленый) с белой точки, то можно получить радиус и я могу нарисовать круг. Однако я не хочу, чтобы нарисовать круг, но только дуги этой окружности между синей точкой и зеленой точкой

Использованием дуги с SVG (A многоточия), я получаю 2 вариант с large_arc_flag

enter image description here

enter image description here

В этом примере: второй вариант является тот, который я хочу: large_arc_flag = 1, но иногда я хочу large_arc_flag = 0. На самом деле, я хочу только дугу, принадлежащую этому кругу. Используя путь с «А», я выбрал 2 дуги из-за пересечения эллипсов.

Как я могу это решить?

Спасибо!

ответ

3

Приведенный случайный центр круга (белая точка), одна случайная точка края (зеленая) и вторая зеркальная точка ребра (синий), вы можете вычислить дугу svg следующим образом.

  • Установка горизонтального и вертикального эллипса радиусы к расстоянию между зелеными и белыми точками
  • Установите ось х вращения к нулю (как вращающийся круг не имеет никакого визуального различия)
  • Установить флаг большой дуги, если зеленая точка находится над белой точкой, в противном случае - (я думаю, что это была ключевая вещь, которую вы задавали)
  • Установите флаг развертки на ноль, потому что желтый путь произвольно нарисованная от левой границы изображения до правого изображения границы, требующих вращение против часовой стрелки от дуги траектории траектории
  • Установите конечную точку в синей точке координаты

Выполните фрагмент кода ниже многократно для различных конфигураций дуги на основе случайных центра и краевых точек.

var xmlns = "http://www.w3.org/2000/svg"; // svg namespace 
 
var doc = document; // common abbreviation 
 
var spc = " "; // space 
 
var com = ","; // comma 
 

 
var wd = 200; // svg width 
 
var ht = 200; // svg height 
 
var svg = doc.querySelector("svg"); // retrieve svg root element 
 
setAttributes(svg, {width: wd, height: ht}); // set the svg dimensions 
 
var cenX = wd/2; // centre the circle horizontally 
 
var cenY = Math.random() * (ht/2) + (ht/4); // pick a random circle centre height 
 

 
var x1 = Math.random() * (wd/3) + (wd/7); // pick a random green point position 
 
var y1 = Math.random() * (ht/2) + (ht/4); 
 

 
var x2 = wd - x1; // mirror the blue point on the green point 
 
var y2 = y1; 
 

 
showPt(cenX, cenY, "white"); // show the white circle centre 
 
showPt(x1, y1, "green"); // show the coloured edge points 
 
showPt(x2, y2, "blue"); 
 

 
var path = doc.createElementNS(xmlns, "path"); // create the yellow path element 
 
setAttributes(path, { // give it colour and width but no fill 
 
    stroke: "yellow", 
 
    "stroke-width": 3, 
 
    fill: "none" 
 
}); 
 
svg.appendChild(path); // add it to the picture 
 

 
var rad = Math.sqrt((x1-cenX)*(x1-cenX) + (y1-cenY)*(y1-cenY)); // calculate the circle radius 
 
var lgArcFlag = (y1 < cenY ? 1 : 0); // the arc will be large if the edge points are above the circle centre 
 
setAttributes(path, { // create the trajectory of the yellow path 
 
    d: 
 
    "M" + 
 
    "0," + y1 + // start it at the left border at the height of the green edge point 
 
    "L" + 
 
    x1 + com + y1 + spc + // draw it to the green edge point 
 
    "A" + // make an arc 
 
    rad + spc + rad + spc + // using the circle radius 
 
    0 + spc + // with no rotation of the ellipse/circle 
 
    lgArcFlag + spc + 0 + spc + // using the large-arc-flag 
 
    x2 + com + y2 + spc + // drawn to the blue edge point 
 
    "L" + 
 
    wd + com + y1 // and drawn straight out to the right border 
 
}); 
 

 
function showPt(x, y, fill) { 
 
    var pt = doc.createElementNS(xmlns, "circle"); 
 
    setAttributes(pt, { 
 
    cx: x, 
 
    cy: y, 
 
    r: 8, 
 
    fill: fill 
 
    }); 
 
    svg.appendChild(pt); 
 
    return pt; 
 
} 
 

 
function setAttributes(el, attrs) { 
 
    var recursiveSet = function(at, set) { 
 
    for (var prop in at) { 
 
     var a = at[prop]; 
 
     if (typeof a === 'object' && a.dataset === undefined && a[0] === undefined) { 
 
     recursiveSet(a, set [prop]); 
 
     } else { 
 
     set.setAttribute(prop, a); 
 
     } 
 
    } 
 
    } 
 
    recursiveSet(attrs, el); 
 
}
<svg> 
 
    <rect id="bkgd" fill="black" x="0" y="0" width="300" height="300" /> 
 
</svg>