Así que tengo una curva bezier D3 SVG como esta :
Quiero obtener las coordenadas X, Y de los puntos con un paso dado desde la ruta D3 de la siguiente manera:
Entonces, para obtener una matriz de pares de coordenadas con pasos iguales. Si es posible, no recalcular la curva de Bezier. ¿Cómo hacer tal cosa en D3js?
Con la ayuda de una función de bisección de aquí , probablemente quieras algo como esto:
const svg = d3.select("svg"), width = 512, height = 200; const data = []; const curve = "curveBasis"; var walk = function() { for (let i = 0, v = 2; i < 50; ++i) { v += Math.random() - 0.5; v = Math.max(Math.min(v, 4), 0); data.push({step: i, value: v}); } } walk(); walkX = d3.scaleLinear() .domain([0, 49]) .range([10, width - 10]); walkY = d3.scaleLinear() .domain([0, 4]) .range([200 - 10, 10]); const line = d3.line() .curve(d3[curve]) .x(d => walkX(d.step)) .y(d => walkY(d.value)); svg .append("path") .attr("id", "svgpath") .attr("d", line(data)) .attr("fill", "none") .attr("stroke", "black"); var svgpath = document.getElementById("svgpath"); var findYatXbyBisection = function(x, path, error){ var length_end = path.getTotalLength(), length_start = 0, point = path.getPointAtLength((length_end + length_start) / 2), // get the middle point bisection_iterations_max = 50, bisection_iterations = 0; error = error || 0.01; while (x < point.x - error || x > point.x + error) { // get the middle point point = path.getPointAtLength((length_end + length_start) / 2); if (x < point.x) { length_end = (length_start + length_end)/2; } else { length_start = (length_start + length_end)/2; } // Increase iteration if (bisection_iterations_max < ++ bisection_iterations) break; } return point.y } for (let i = 0; i < data.length; ++i) { console.log(findYatXbyBisection(walkX(i), svgpath, 0.01).toFixed(4)); }
<html> <head> <meta charset="utf-8" /> <title>SVG Line</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.1.1/d3.min.js" integrity="sha512-COTaPOlz12cG4fSfcBsxZsjauBAyldqp+8FQUM/dZHm+ts/jR4AFoJhCqxy8K10Jrf3pojfsbq7fAPTb1XaVkg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> </head> <body> <svg id="chart" width="512" height="200"> </svg>
Tenga en cuenta que los valores Y devueltos son coordenadas SVG, por lo que comienzan en 0 desde la parte superior de la página. Verifique la función de rango utilizada en la función walkY para actualizar cómo debe invertir los valores para los gráficos de barras y líneas típicos en D3.js.
Y, por supuesto, en lugar de iniciar sesión en la consola, puede enviar los valores a su matriz personalizada y usar un valor de intervalo diferente, por ejemplo, 1/n del ancho total de la línea (ruta) en lugar de 1/50 que he usado (para 50 puntos de datos) .