PDA

Просмотр полной версии : Простая задачка


LostWarrior
09.07.2002, 11:46
Народ!
Очень простая задача для математика и программиста:
есть две точки p1 и p2 соответственно с координатами x и y каждая. Точка p1 двигается по заданной траектории.
Требуется:
двигать точку p2 по той-же траектории на расстоянии r от точки p1.
!!!Важно: не по ПАРАЛЛЕЛЬНОЙ, а по ТОЙ-ЖЕ траектории.

greyshaman
09.07.2002, 11:59
по какой траектории или по какой закономерности?
на каком расстоянии?

derhab
09.07.2002, 12:02
Я не программист, но по моему это делается посредством getProperty, т.е второй точке динамически присваиваются значения _x и _y первой точки

DeliMIter
09.07.2002, 12:09
2derhab

Я в шоке 8-0

2LW

Все действительно очень зависит от того, как задается таектория.

derhab
09.07.2002, 13:14
2DeliMIter Да не стоит так переживать :) Я имею в виду, что если одному клипу задана траектория( не программно, а с помощью банального пути в слое), то второй клип пойдет по той же кривой при помощи getProrerty. Разве нет? Я только что пробовал, все ок. И просьба еще, относится немного снисходительнее, я просто пытаюсь понять...

Armen Khanoyants
09.07.2002, 13:20
привет
допустим у тебя формула траектории...
короче вот файл...
там 2 примера...
одна траектория програмная:-) т.е. просто движение по cos...
второй пример motion guide...
наверно тебе нужен 2-й...

derhab
09.07.2002, 13:28
2Armen Khanoyants Может ты объяснишь от чего уважаемый DeliMIter был в шоке? Твой второй пример в точности то, что я имел в виду.

DeliMIter
09.07.2002, 13:40
Я сам объясню.

Во-первых setProperty это Flash 4, но видимо так пишут в книжках (которых я не читал ни одной). Макромедия рекомендует пользовать

MovieClip._x = value;

и она права - это значительно читабельнее, и подход объектный.

Во вторых твой ответ звучал как

- Как открыть этот замок?
- Ключом...

;)))))))))

Armen Khanoyants
09.07.2002, 13:40
2derhab:
а я тут причем?:)
в шоке, в шоке:)

LostWarrior
09.07.2002, 13:40
Все немного сложнее.

Итак: растояние между точками "r". это я уже писал. это константа. То есть просто присваивать не получится. Так будет работать только если скорость первой точки тоже равна "r".
А тректория... ну скажем первой точкой кто-то управляет с клавиатуры. То есть траектория абсолютно абстрактная, от нее ничего не зависит.

Ну и, естественно, все делается в AS

Armen Khanoyants
09.07.2002, 13:42
2DeliMIter:
ключом:)
LOL
_x рулит!

Armen Khanoyants
09.07.2002, 13:43
2LostWarrior:
ну и в чем проблема?
по моему из примера все ясно и так...
или нет?

Armen Khanoyants
09.07.2002, 13:44
2LostWarrior: ты хоть скачал-то пример, который я тебе сделал?

LostWarrior
09.07.2002, 13:47
Пример я смотрел. Это не то. вторая точка должна СЛЕДОВАТЬ за первой, а не двигатся пареллельно ей. Это две большие разницы.

Armen Khanoyants
09.07.2002, 13:49
ну поставь вторую 2-ю точку сзади 1-й и все...
или нет?

derhab
09.07.2002, 13:50
Ок, все в шоке :) Просто это для вас само собой разумеется, я ж о многих вещах догадываюсь интуитивно... Кроме того, не такой уж плохой ответ про ключ, бывает, некоторые пытаются сломать дверь ;)

LostWarrior
09.07.2002, 13:52
где сзади??? :confused: Понятие "сзади" теряет смысл, если ты не знаеш где у тебя будет "перед" в следующую секунду.

Nox Noctis
09.07.2002, 14:15
ну вы тут нагородили :eek:
'шок' - это по-вашему :)))))

// c1 = {x:..., y:...}; - координаты начала движения p1
p1._x = c1.x + A*Math.cos(dy);
p1._y = c1.y + dy;
// dy - параметр, т.е. будет вертикальная косинусоида (это просто для примера)
// A - это амплитуда косинуса

// тогда вторую точку запустим точно так же, но из другого "начала"
с2 = {x:p1._x, y:p1._y};
p2._x = c2.x + A*Math.cos(dy);
p2._y = c2.y + dy;

...расстояние, между p1 и p2 зависит от того насколько позже стартанет p2 :)))

(если нужно конкретное расстояние 'r' то где-нить по ентерфрейму надо вычислять корень из суммы квадратов соотв. координат точек c1 и p1... и когда значение расстояния будет >= r - запускаем p2)

зы: 2LostWarrior помощь

LostWarrior
09.07.2002, 14:34
Это уже ближе.
НО!
Очень принципиальный момент. Простой пример:
например функция cos(a) и в какой-то момент "а" изменяется.
тогда первая точка должна сразу изменить траекторию, а вторая продолжать двигатся по старой пока не достигнет этого места, и только потом повернуть.
Вы будете смеятся, но это ОЧЕНЬ важно!

andr_sky
09.07.2002, 14:38
эта задача невыполнима (условия у ней такие)

часный случай /ошибка/:

если Т1 точка будет двигаться по прямой,
то Т2 будет тянуться за ней по её СЛЕДУ
на расстоянии R=const (пока всё ok),
а потом вдруг траектория Т1 развернётся на
180 градусов с радиусом <r> окружности поворота
намного меньшим чем константа <R> (0>=r<R)
и получится ситуация что Т1 будет двигаться
навстречу к Т2 -- R уже не будет константой.
(error - точке Т2 некуда деваться =
надо и по следу идти, и расстояние держать)

http://a100.by.ru/nn.jpg

задачу можно решить если R будет не расстоянием между
Т1 и Т2, а будет количественным измерением пути между
этими точками по траектории Т1.

LostWarrior
09.07.2002, 14:55
Это и подразумевалось. Растояние вдоль траектории.

Armen Khanoyants
09.07.2002, 15:02
2LostWarrior:
вот то что ты хотел
делал 5 мин
вот сразу не выложил, т.к. что-то с провом...
ну халява:-) как говорится дореному конью...

Nox Noctis
09.07.2002, 15:09
минутку :))
по-моему кто-то прогуливал школьные уроки физики :))

расстояние - это отрезок прямой между двумя точками
длина траектории - это путь
все что ты до сих пор относилось к перемещению, а не к длине пути :))

вообще можно сделать вот как:
первая точка идет по какой-то там траетории и записывает на каждом шаге свое положение в массив точек {x:..., y:...} вторую точку запускаем тогда, когда сумма длин отрезков по полученным точкам >= определенному значению... это быдет конечно аппроксимация, но что делать...

и вторую точку вести уже надо будет по точкам из массива, удаляя постепенно пройденные (по принципу очереди fifo)

Armen Khanoyants
09.07.2002, 15:15
2Nox Noctis: кто прогуливал?

andr_sky
09.07.2002, 15:19
я вот тут нафигачил.
траектория формируется мышкой.

Nox Noctis
09.07.2002, 15:19
кто-кто... дух тени отца гамлета :))

Armen Khanoyants
09.07.2002, 15:30
2andr_sky: для чего "фигачить" нафигаченное?:-)

Nox Noctis
09.07.2002, 16:16
чистый AS :))

// рисуем точки А и В
this.createEmptyMovieClip("A", 1);
this.createEmptyMovieClip("B", 2);
A.lineStyle(15, 0), B.lineStyle(15, 32768);
A.lineTo(.15, 0), B.lineTo(.15, 0);
// массив контрольных точек, расстояний между ними и заданная дистанция
B.guide=[], B.way=[], B.lim=100;
// двигаем первую точку
A.onMouseMove = function() {
tellTarget (this) {
prv = {x:_x, y:_y};
nxt = {x:_root._xmouse, y:_root._ymouse};
_x=nxt.x, _y=nxt.y;
// величина аппроксимации зависит от этого условия
if ((tmp=_root.dist(prv, nxt))>1) {
// добавляем в массив точку
_root.B.guide.push(nxt);
// добавляем в масси расстояние от предыдущей
_root.B.way.push(tmp);
// суммируем расстояние
_root.B.len += tmp;
_root.B.active = _root.B.len>=_root.B.lim;
}
}
};
// двигаем вторую точку
B.onEnterFrame = function() {
tellTarget (this) {
if (active) {
_x = guide[0].x;
_y = guide[0].y;
len -= way[0];
guide.splice(0, 1);
way.splice(0, 1);
active = len>=lim;
}
}
};
dist = function (a, b) {
return Math.sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
};
насколько точно будет вторая точка следовать за первой зависит от скорости движения и точности аппроксимации... если двигать мышкой (в моем примере) - то вторая точка намного отстает... но траектория при этом не теряется :))

зы:
у andr_sky точки перемещаются странно, если вести одну навтречу другой.
у Армена второй объект повторяет траекторию первого, а просто следует за ним.

Nox Noctis
09.07.2002, 16:36
в последней фразе я хотел сказать " 'не' повторяет траекторию" :))

LostWarrior
09.07.2002, 16:38
Похоже ничего кроме старого доброго масива с координатами придумать невозможно. А жаль.
derhab в самом начале предложил присваивать координаты первой точки второй. А что если между ними расположить еще "r" невидимых точек и по циклу с конца переприсваивать координаты?

Всем спасибо за внимание, и за предложения.

Armen Khanoyants
09.07.2002, 17:01
2LostWarrior: а что тебе еще надо?

derhab
09.07.2002, 17:04
2LostWarrior Да, странно. а что тебя в последнем случае то не устраивает? :confused: Разве это не то что ты хотел?

uri-uri
09.07.2002, 22:40
2 LostWarrior & All
Я попытался это себе представить так: по выгрызаемому им в земле (...возможны варианты) проходу ползет червяк. 1 точка - голова, 2 - жопа. Соответственно жопа следует за головой на расстоянии=длина тела (ну ето такой несокращаемый червяк - радикулит разбил :D ). Отсюда - и соответствующий математический аппарат. Может аппроксимировать участок пути от головы в сторону жопы кусочками прямых с требуемой точностью? Тогда даже можно позу жопы рассчитать. Вот...
Мож я не к месту, но такая живая ассоциация в воспаленном мозге вспыхнула... :rolleyes:

Nox Noctis
09.07.2002, 23:49
дык фишка в том, что этот вариант уже приведен выше :))

...правда не настолько живописно - надо отдать тебе должное :))))

а "математический аппарат для разбитого радикулитом червяка" рулит :)))))))))))))))))

greyshaman
10.07.2002, 15:33
Вообще то есть вариант с апроксимацией по 3 точкам. Следующие объекты, будут лежать +- погрешность на кривой проходящей через них.
Продолжать?

LostWarrior
10.07.2002, 15:50
Не подходит. При передвижении одной из точек кривая меняется. Если в задаче точек не две а больше, которые следуют одна за другой, и каждую следующую так расчитывать, то буде наблюдатся эффект затухания колебаний к концу последовательности.

greyshaman
10.07.2002, 15:58
С какой это радости если они будут лежать на кривой Бизье?

LostWarrior
10.07.2002, 19:36
Потому-что через два разных набора точек, даже если второй набор сдвинут относительно первого вдоль той-же кривой, по формулам Бизье кривые получаются разные.

Nox Noctis
10.07.2002, 19:50
ребят, по-моему вы перегрелись слегка :))
объяснит кто-нить - чем не устраивают уже приведенные решения ??


зы: Безье (Bezier) :P

LostWarrior
10.07.2002, 20:03
Народ! Я это замутил! ТУФТА!!!
Все отлично когда последовательно точек <100. Если каждая из них статичный клип из одного кадра. Дальше скорость проигрывания мувика катострофически падает!

Надо что-то делать.

Nox Noctis
10.07.2002, 20:26
что ты хочешь сделать ?
объясни, а ?

объясни как именно формируется траектория первой точки.
откуда берется ?
и вообще - чего ты добиваешься-то ? может все значительно проще ? :))

LostWarrior
11.07.2002, 10:21
Все банально.
Всем известная игрушка - worm. Главное отличие от оригинала - то что при нажатии кнопок "влево", "вправо" он поворачивает не на 90 градусов, а на 1. Вот и задача. В какой-то момент игры, причем в самом начале, у него становится столько точек, что мувик тормозит.
Будут идеи как его ускорить?

greyshaman
11.07.2002, 10:49
2 Nox Судьба такая, грам-матика часто подводит ;)

2 LW Не менять координаты сегментов(аттачить объект в позицию головы, голову смещать, хвост отрезать).Сегмент сделать из кадров темнее светлее. Не делать хиттест.
Пересечение определять по массиву.

Fisher
11.07.2002, 13:30
Такой подойдет? :)

LostWarrior
11.07.2002, 15:05
2 Fisher: Красивые шарики :) а теперь представь что их 100 шт. и прикинь скорость работы.

2 greyshaman: в тестовом варианте кроме движения вообще ничего нет (хиттест, случайное появление целей, даже сталкивания не проверяется - все закомментировал) а сегмент - круг желтого цвета диаметром 6 pix. А насчет не двигать сегменты - это я попробую - завтра скажу что вышло.

andr_sky
11.07.2002, 15:34
вот нафигачил ещё.
"чистый код" или как его там....
сегменты не двигаются


len = 100;
id = len;
createEmptyMovieClip("z", 0);
z._alpha=0;
tellTarget ("z") {
beginFill(0x00ff00, 70);
moveTo(0, 0);
curveTo(10, 0, 10, -10);
curveTo(10, -20, 0, -20);
curveTo(-10, -20, -10, -10);
curveTo(-10, 0, 0, 0);
endFill();
}
for (i=1; i<len; i++) {
duplicateMovieClip("z", "z"+i, i);
}
onMouseMove = function () {
removeMovieClip("z"+(id-len));
id++;
duplicateMovieClip("z", "z"+id, id);
this["z"+id]._x = _xmouse;
this["z"+id]._y = _ymouse;
this["z"+id]._alpha = 100;
};


len - кол-во сегментов.
при 100 шт мой p3-550 напрёгся на 25%

andr_sky
11.07.2002, 16:03
это с плавным движением,
головой и хвостом.
теперь напряг камня 50%


len = 100;
id = len;
createEmptyMovieClip("z", 0);
z._alpha = 0;
tellTarget ("z") {
beginFill(0x00ff00, 30);
moveTo(0, 10);
curveTo(10, 10, 10, 0);
curveTo(10, -10, 0, -10);
curveTo(-10, -10, -10, 0);
curveTo(-10, 10, 0, 10);
endFill();
}
for (i=1; i<len; i++) {
duplicateMovieClip("z", "z"+i, i);
}
onMouseMove = function () {
removeMovieClip("z"+(id-len));
tellTarget ("z"+(id-len+1)) {
_xscale += 100, _yscale += 100;
}
id++;
duplicateMovieClip("z", "z"+id, id);
tellTarget ("z"+id) {
_x = (_x+_root.dx);
_y = (_y+_root.dy);
_root.dx += ((_root._xmouse-_x)/20);
_root.dy += ((_root._ymouse-_y)/20);
_yscale += 100, _xscale += 100;
_alpha = 100;
}
tellTarget ("z"+(id-1)) {
_xscale -= 100, _yscale -= 100;
}
};

greyshaman
11.07.2002, 17:28
2 LW не увлекайся. Утром (деньги) массив- его представление- определение пересечения (это важно для worm),вечером (стулья) визуализация. Задачка решается в комплексе.

LostWarrior
11.07.2002, 17:46
;) Это все готово, просто закомментировано "до выяснения".

uri-uri
13.07.2002, 01:21
2 All
Мужики! Вы тут напрягаетесь по полной программе, а ведь и без того жарко...
Може я опять не в тему, но, типа - линия задержки - может проще будет. Ну, жопа будет там, где сейчас голова скажем через 10 кадров. Вот мы ей и передаем координаты головы 10 кадров назад. Счетчик кадров и массив (стек) на эти кадры. Соответственно, для головожопы каждого сегмента тот же стек, но промежуточные значения. Ведь скорость перемещения не меняется? - в противном случае количество кадров будет переменно. Но это тоже моно отловить.