Как пройти путь из точки A в точку D за определенное время?

Есть путь, состоящий из нескольких точек - A, B, C, D, я прокручиваю некую область от 0 до 100%, как узнать в какой точке пути будет находится объект при 35% например?

Путь - это ломаная кривая (никаких Безье). Ума не приложу, как вычислять координаты объекта на этом пути по мере прокрутки. Точек на пути может быть больше, чем 4. Подскажите, в какую сторону копать?
  • Вопрос задан
  • 2765 просмотров
Решения вопроса 2
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
var points = [{x: 0, y: 0}, {x: 0, y: 50}, {x: 10, y: 50}, {x: 10, y: 0}];
var segLen = [];
var totalLen = 0;
for (var i = 0; i < points.length-1; i++) {
    var l = Math.sqrt((points[i+1].x-points[i].x)*(points[i+1].x-points[i].x)+
                      (points[i+1].y-points[i].y)*(points[i+1].y-points[i].y));
    segLen.push(l);
    totalLen += l;
}
var percent = 55;
var needLen = totalLen*percent/100;
for (var i = 0; i < points.length-1 && needLen > 0; i++)
    if (needLen >= segLen[i]) {
        // пройти путь points[i] - points[i+1]
        needLen -= segLen[i];
    } else {
        x = points[i].x+(points[i+1].x-points[i].x)*needLen/segLen[i];
        y = points[i].y+(points[i+1].y-points[i].y)*needLen/segLen[i];
        // пройти путь points[i] - {x, y}
        needLen = 0;
    }
Ответ написан
Комментировать
EvilMan
@EvilMan
1. Сначала вам нужно узнать суммарную длину всего пути,
2. Обходя следующую точку, вы можете заносить в массив значений расстояние от начала пути до этой точки.
3. На выходе получаете массив с абсолютными значениями.
4. Опционально для ускорения можно преобразовать их в процентные.

Теперь, чтобы определить процент от пути, надо сделать следующее:
1. Если в массиве у нас абсолютные значения, то надо процентное значение преобразовать в абсолютное.
2. Последовательно идёте по массиву, и находите две точки, между которыми находится искомая точка останова.
3. Теперь всего лишь осталось уточнить координаты точки останова. Это не так сложно, так как вам известны координаты точек, и расстояние точки останова до этих точек.
Если интересно, могу кинуть псевдокод, так как в JS не шибко силён.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
Если точность не нужна - достаточно смотреть по проекции ломанной, если нужна точность - вам никто не мешает посчитать длину ломанной линии (зная угл к нормали).
Ответ написан
@GreatRash Автор вопроса
Спасибо, друзья, всё получилось. Вот такой код у меня вышел:

function lerp(a, b, t) {
	var p = {};

	p.x = (1 - t) * a.x + t * b.x;
	p.y = (1 - t) * a.y + t * b.y;

	return p;
}

function len(p1, p2) {
	var p = {};

	p.x = p2.x - p1.x;
	p.y = p2.y - p1.y;

	return Math.sqrt(p.x * p.x + p.y * p.y);
}

var path = [
	{x: 975, y: 4880},
	{x: 1375, y: 4880},
	{x: 1375, y: 4480},
	{x: 975, y: 4480}
];

var pathSegments = [];
var pathLength = 0;

var percent = .35;

for (var i = 0; i < path.length - 1; i += 1) {
	pathSegments.push({
		p1: path[i],
		p2: path[i + 1],
		len: len(path[i], path[i + 1])
	});

	pathLength += pathSegments.slice(pathSegments.length - 1, pathSegments.length)[0].len;
}

var needLength = pathLength * percent;
var pathTail = needLength;
var findSeg = 0;

for (var j = 0; j < pathSegments.length; j += 1) {
	if (needLength >= pathSegments[j].len) {
		needLength -= pathSegments[j].len;
	} else {
		findSeg = j;
		break;
	}
}

var tailPercent = needLength / pathSegments[findSeg].len;

console.log(lerp(pathSegments[findSeg].p1, pathSegments[findSeg].p2, tailPercent));
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы