2013-09-05 13 views
5

Staram się znaleźć właściwą geometrię do znalezienia środkowego punktu ścieżki wzdłuż łuku. Powiedzmy, że mam dwa punkty: x1, y1 i x2, y2. w linii tak jak poniżej:obliczanie łuku/punktu w ścieżce d3

arc

x1, y1 jest A. X2, Y2 jest B.

Im próby zapisu funkcję, która może dostarczyć i odległość (-1 lub 1) na powyższym obrazie i zwraca X i Y coords. W ten sposób mogę dodać środkowy punkt na ścieżce, aby uczynić linię poniższym:

arc

[aktualizacja]

Musisz użyć kąta dowiedzieć się, X i Y im linii patrząc dla. Poniżej pokazano, że linia jest 45 stopni, jedna strona trójkąta to 5, jedna strona to 1. Z tego można obliczyć x i y.

arc

Myślę, że zorientowaliśmy się z poniższym kodzie i skrzypce fiddle przykład:

var svgContainer = d3.select("#canvas").append("svg") 
             .attr("width", 400) 
             .attr("height", 400); 

var lineData = [ { "x": 0, "y": 0}, { "x": 100, "y": 100}]; 

var midPoint = { 
    x:Math.abs(lineData[1].x - lineData[0].x)/2, 
    y:Math.abs(lineData[1].x - lineData[0].x)/2 
}; 

function calcAngle(x1, x2, y1, y2) { 
    var calcAngleVal = Math.atan2(x1-x2,y1-y2)*(180/Math.PI); 

    if (calcAngleVal < 0) { 
     calcAngleVal = Math.abs(calcAngleVal); 
    } else{ 
     calcAngleVal = 360 - calcAngleVal; 
    } 

    return calcAngleVal; 
} 

var angle = calcAngle(lineData[0].x, lineData[1].x,lineData[0].y,lineData[1].y); 


var sin = Math.sin(angle * Math.PI/180); 
var cos = Math.cos(angle * Math.PI/180); 

var xLen = Math.abs(lineData[1].x - lineData[0].x)/2; 
var yLen = Math.abs(lineData[1].y - lineData[0].y)/2; 


var n = 1.5; 

var midpointArc = { 
    x: midPoint.x + (sin * (n * 25)), 
    y: midPoint.y + (cos * (n * 25)) 
}; 

lineData.splice(1,0,midpointArc); 

var lineFunction = d3.svg.line() 
         .x(function(d) { return d.x; }) 
         .y(function(d) { return d.y; }) 
         .interpolate("basis"); 

var lineGraph = svgContainer.append("path") 
          .attr("d", lineFunction(lineData)) 
          .attr("stroke", "blue") 
          .attr("stroke-width", 1) 
          .attr("fill", "none"); 

var pathEl = lineGraph.node(); 
var curvedMidpoint = pathEl.getPointAtLength(pathEl.getTotalLength()/2); 

svgContainer.append("circle") 
      .attr('r',5) 
      .attr('cx', curvedMidpoint.x) 
      .attr('cy', curvedMidpoint.y) 

Odpowiedz

6

Aby znaleźć punkt środkowy każdej ścieżki (nie tylko łuku):

var pathEl = d3.select('#pathId').node(); 
var midpoint = pathEl.getPointAtLength(pathEl.getTotalLength()/2); 

przystosowany z Duopixel's answer i bl.ockus.

+0

Dzięki. Jest to pomocne po narysowaniu linii (właściwie ścieżki), ale moim problemem było to, że chciałbym uzyskać punkt środkowy na poziomie N (-1 lub 1 na rysunku) przed narysowaniem ścieżki. Kluczem jest to, że musisz obliczyć stopień linii, aby uzyskać x, y punktów szukam. Weź krosna w aktualizacji. chciałbym usłyszeć, jeśli uważasz, że jest lepszy sposób na uzyskanie odpowiedzi. – jamescharlesworth

+0

co jeśli chcesz poznać punkt w wyimaginowanej ścieżce, która nie znajduje się w DOM, po prostu umieścić element koła na SVG (DOM) na tej współrzędnej? Wygląda na to, że potrzebujesz wstrzykiwać ścieżkę tylko po to, aby obliczenia zadziałały? – vsync

+0

Należy pamiętać, że ta funkcja została uznana za nieaktualną https://developer.mozilla.org/en-US/docs/Web/API/SVGPathElement/getPointAtLength –