如何在多个控制点之间获得线性插值点?
How to get linear interpolated points among several control points?
例如我有3点:(y:0, x:0), (y:100, x:10), (y:50, x:100)
。所以我需要在这条多段线中得到 10 个点,它们之间的距离相等。我知道2个点之间怎么取分,但是几个点之间我肯定不知道怎么取。
为了接收两点之间的距离,我使用这个:
function getDistance(y1,x1,y2,x2){
return Math.sqrt(Math.pow(y2-y1, 2) + Math.pow(x2-x1, 2))
}
为了计算单点,我使用它:
function interpolate(a, b, frac){
return {
y: a.y+(b.y-a.y)*frac,
x: a.x+(b.x-a.x)*frac
};
}
谁能帮帮我?
这工作正常(例如,我在同一条线上使用 3 个点,但它应该适用于每个组合)
function getDistance({y: y1, x:x1}, {y:y2, x:x2}){
return Math.sqrt(Math.pow(y2-y1, 2) + Math.pow(x2-x1, 2))
}
function interpolate(a, b, frac){
return {
x: a.x+(b.x-a.x)*frac,
y: a.y+(b.y-a.y)*frac,
};
}
//generate N point in a line
function generateOnLineEveryDistance(a, b, n, distance){
let res = [];
for(let i = 0; i < n ; i++){
// add a point interpolating on a line after (i + 1) * distance from the beginning point (i+1 to avoid the starting point 0,0)
res.push(interpolate(a, b, (i + 1) * distance))
}
return res;
}
function generate(points, n){
// calculate total distance to find out how distant we have to place the points
let totalDistance = 0;
for(let i = 1; i < points.length; i++){
totalDistance += getDistance(points[i - 1], points[i])
}
// distance to place the points
const pointDistance = totalDistance / (n - 1);
// the first point is always included
let res = [points[0]];
// now, we will consider a segment as point[i - 1] & point[i], and we will consider only the piece where we can fit point:
// eg. in a segment long 10 ([x:0, y:0], [x:0, y:10]), and a pointDistance of 4, we will consider only [x:0, y:0], [x:0, y:8]
// and the remainder is 2... this remainder will be used in the next segment, "appending it at the beginning"
// let's say the second segment is [x:0, y:10], [x:0, y:20], with the remainder it will be [x:0, y:8], [x:0, y:20]
let remainder = 0;
for(let i = 1; i < points.length ; i++){
// add the remainder if exists at the beginning of the current segment (point[i-1], point[i])
// source
if(remainder > 0){
let a = points[i];
let b = points[i - 1];
let lengthAB = Math.sqrt(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2))
points[i - 1].x = b.x + (b.x - a.x) / lengthAB * remainder;
points[i - 1].y = b.y + (b.y - a.y) / lengthAB * remainder;
}
// points we need to generate
let nPoints = Math.floor(getDistance(points[i - 1], points[i]) / pointDistance)
// remainder to add to the next iteration
remainder = getDistance(points[i - 1], points[i]) - nPoints * pointDistance;
// add to the result the points
res = [
...res, // previous result
...generateOnLineEveryDistance( // new points
points[i - 1], // first point to consider
points[i], // second point to consider
nPoints, // number of points to generate
pointDistance / getDistance(points[i - 1], points[i]) // the ratio we want to use to generate them
)
]
}
// small fix in case of .333333 decimals that will "miss" the last point because it's .9999 and not 1.00000
if(res.length < n){
res = [...res, points[points.length - 1]]
}
return res;
}
const points = [
{
x: 0,
y: 0
} , {
x: 0,
y: 10
} , {
x: 0,
y: 20
}
]
console.log(generate(points, 4))
但是,我可以看到 this library 已经这样做了,我还没有检查出来,但也许值得检查一下,因为我提供的代码未经测试且不可读
更新:
我已经根据他们提供的示例对其进行了测试,并且返回了相同的结果,所以 GG
例如我有3点:(y:0, x:0), (y:100, x:10), (y:50, x:100)
。所以我需要在这条多段线中得到 10 个点,它们之间的距离相等。我知道2个点之间怎么取分,但是几个点之间我肯定不知道怎么取。
为了接收两点之间的距离,我使用这个:
function getDistance(y1,x1,y2,x2){
return Math.sqrt(Math.pow(y2-y1, 2) + Math.pow(x2-x1, 2))
}
为了计算单点,我使用它:
function interpolate(a, b, frac){
return {
y: a.y+(b.y-a.y)*frac,
x: a.x+(b.x-a.x)*frac
};
}
谁能帮帮我?
这工作正常(例如,我在同一条线上使用 3 个点,但它应该适用于每个组合)
function getDistance({y: y1, x:x1}, {y:y2, x:x2}){
return Math.sqrt(Math.pow(y2-y1, 2) + Math.pow(x2-x1, 2))
}
function interpolate(a, b, frac){
return {
x: a.x+(b.x-a.x)*frac,
y: a.y+(b.y-a.y)*frac,
};
}
//generate N point in a line
function generateOnLineEveryDistance(a, b, n, distance){
let res = [];
for(let i = 0; i < n ; i++){
// add a point interpolating on a line after (i + 1) * distance from the beginning point (i+1 to avoid the starting point 0,0)
res.push(interpolate(a, b, (i + 1) * distance))
}
return res;
}
function generate(points, n){
// calculate total distance to find out how distant we have to place the points
let totalDistance = 0;
for(let i = 1; i < points.length; i++){
totalDistance += getDistance(points[i - 1], points[i])
}
// distance to place the points
const pointDistance = totalDistance / (n - 1);
// the first point is always included
let res = [points[0]];
// now, we will consider a segment as point[i - 1] & point[i], and we will consider only the piece where we can fit point:
// eg. in a segment long 10 ([x:0, y:0], [x:0, y:10]), and a pointDistance of 4, we will consider only [x:0, y:0], [x:0, y:8]
// and the remainder is 2... this remainder will be used in the next segment, "appending it at the beginning"
// let's say the second segment is [x:0, y:10], [x:0, y:20], with the remainder it will be [x:0, y:8], [x:0, y:20]
let remainder = 0;
for(let i = 1; i < points.length ; i++){
// add the remainder if exists at the beginning of the current segment (point[i-1], point[i])
// source
if(remainder > 0){
let a = points[i];
let b = points[i - 1];
let lengthAB = Math.sqrt(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2))
points[i - 1].x = b.x + (b.x - a.x) / lengthAB * remainder;
points[i - 1].y = b.y + (b.y - a.y) / lengthAB * remainder;
}
// points we need to generate
let nPoints = Math.floor(getDistance(points[i - 1], points[i]) / pointDistance)
// remainder to add to the next iteration
remainder = getDistance(points[i - 1], points[i]) - nPoints * pointDistance;
// add to the result the points
res = [
...res, // previous result
...generateOnLineEveryDistance( // new points
points[i - 1], // first point to consider
points[i], // second point to consider
nPoints, // number of points to generate
pointDistance / getDistance(points[i - 1], points[i]) // the ratio we want to use to generate them
)
]
}
// small fix in case of .333333 decimals that will "miss" the last point because it's .9999 and not 1.00000
if(res.length < n){
res = [...res, points[points.length - 1]]
}
return res;
}
const points = [
{
x: 0,
y: 0
} , {
x: 0,
y: 10
} , {
x: 0,
y: 20
}
]
console.log(generate(points, 4))
但是,我可以看到 this library 已经这样做了,我还没有检查出来,但也许值得检查一下,因为我提供的代码未经测试且不可读
更新:
我已经根据他们提供的示例对其进行了测试,并且返回了相同的结果,所以 GG