パスを描画するための一連のポイントがあります。
let path=svg.append("path").attr("id","path")
.data([points])
.attr("d", d3.line()
.curve(d3.curveCatmullRom));
ここで、ポイント間のパスの距離を取得して、セグメントに分割できるようにします。距離を増やして、ポイント(5に四捨五入)が最初のポイントセットのポイントと一致するかどうかを確認し、一致するたびに距離を取得してみました。次に、そこまでポイントをリストとして保存します。
ここに、xyArray
私が追加するポイントd
のリストとリストseg
もあります。
function distanceBetween2Points(path, xyArray) {
let distance = 0;
xyArray.forEach(function(d,i)
{
let flag=1;
seg=[];
while(flag)
{let pt=path.getPointAtLength(distance);
if(round5(pt.x)==round5(d.x) && round5(pt.y)==round5(d.y))
{console.log("d",i);
d.d=distance;
d.seg=seg;
flag=0;
break;}
seg.push([pt.x,pt.y]);
distance++;}
return 0;
});
}
データによっては、機能する場合もありますが(正確ではありませんが)、機能しない場合もあります。距離を取得するためのより良い方法はありますか?
これはd3ではなくバニラJavaScriptを使用したデモですが、お役に立てば幸いです。
この関数getLengthForPoint(p,thePath)
は、指定された点pのパス上の距離を計算しています。変数を設定していますlet precision = 100;
。パスの長さによっては、この値を別の値に変更することもできます。
また、パスが同じポイントを複数回通過する可能性があることにも注意してください。これは注意が必要で、エラーが発生する可能性があります。
また、ご存知かもしれませんが、ポイントまでのおおよその距離がわかります。この例では、ポイントp1 = {x:93.5,y:60}
。計算された長さの点には、次の座標があります。{x:93.94386291503906,y: 59.063079833984375}
// some points on the path
let p1 = {x:93.5,y:60}
let p2 = {x:165,y:106}
//the total length of the path
let pathLength = thePath.getTotalLength();
let precision = 100;
let division = pathLength / precision;
function getLengthForPoint(p,thePath){
let theRecord = pathLength;
let theSegment;
for (let i = 0; i < precision; i++) {
// get a point on the path for thia distance
let _p = thePath.getPointAtLength(i * division);
// get the distance between the new point _p and the point p
let theDistance = dist(_p, p);
if (theDistance < theRecord) {
// if the distance is smaller than the record set the new record
theRecord = theDistance;
theSegment = i;
}
}
return(theSegment * division);
}
let theDistanceOnThePath = getLengthForPoint(p1,thePath);
//if you calculate the coords of a point at the calculated distance you'll see that is very near the point
console.log(thePath.getPointAtLength(theDistanceOnThePath));
let theDistanceBetween2PointsOnThePath = getLengthForPoint(p2,thePath) - getLengthForPoint(p1,thePath);
// a helper function to measure the distance between 2 points
function dist(p1, p2) {
let dx = p2.x - p1.x;
let dy = p2.y - p1.y;
return Math.sqrt(dx * dx + dy * dy);
}
svg{border:solid}
<svg viewBox="0 10 340 120">
<path id="thePath" fill="none" stroke="black" d="M10, 24Q10,24,40,67Q70,110,93.5,60Q117,10,123.5,76Q130,142,165,106Q200,70,235,106.5Q270,143, 320,24"></path>
<circle cx="93.5" cy="60" r="2" fill="red"/>
<circle cx="165" cy="106" r="2" fill="red"/>
</svg>
パス上の2点間の距離を取得するには、次のようにします。
let theDistanceBetween2PointsOnThePath = getLengthForPoint(p2,thePath) - getLengthForPoint(p1,thePath);
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加