2013-09-05 11 views
5

Non riesco a capire la geometria corretta per trovare un punto medio di un percorso lungo un arco. Diciamo che ho due punti: x1, y1 e x2, y2. in fila come qui sotto:calcolo dell'arco/punto nel percorso d3

arc

x1, y1 è A. x2, y2 è B.

Nel tentativo di scrivere una funzione che posso fornire la distanza (-1, o 1) nell'immagine sopra e restituisce le coordinate xey. In questo modo posso aggiungere un punto intermedio nel percorso per rendere la linea di seguito:

arc

[aggiornamento]

È necessario utilizzare l'angolo della figura linea su x e im y cercando per. Di seguito viene mostrato che la linea è di 45 gradi, un lato del triangolo è 5, un lato è 1. Da questo, è possibile calcolare xey.

arc

Credo di aver capito con il codice qui sotto e violino fiddle esempio:

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) 

risposta

6

Per trovare il punto medio di ogni percorso (non solo un arco):

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

adattato da Duopixel answer e bl.ockus.

+0

Grazie. Ciò è utile quando viene disegnata la linea (in realtà il percorso), ma il mio problema era che voglio ottenere il punto centrale su N (-1 o 1 nel mio disegno) prima che il tracciato venga disegnato. La chiave è che devi calcolare il grado della linea per ottenere i punti x, y che stai cercando. Prendi un telaio durante l'aggiornamento. mi piacerebbe sentire se pensi che ci sia un modo migliore per arrivare alla risposta. – jamescharlesworth

+0

Cosa fare se si desidera conoscere un punto in un percorso immaginario che non si trova nel DOM, solo per posizionare un elemento cerchio su SVG (DOM) in corrispondenza di tale coordinata? sembra che tu abbia bisogno di iniettare un percorso solo perché il calcolo funzioni? – vsync

+0

Attenzione, la funzionalità è stata deprecata https://developer.mozilla.org/en-US/docs/Web/API/SVGPathElement/getPointAtLength –

Problemi correlati