Як інтерполювати навколо прямокутника?


11

Я хочу зробити фантазійну анімацію, де точка об'їжджає прямокутник. Я хочу одночасно знайти позицію точки t.

Прямокутник дається X, Y, Widthі Height.

прямокутник, навколо нього за годинниковою стрілкою

Чи існує алгоритм для цього?

Я використовував sin/ cosдля кіл. Який еквівалентний підхід для прямокутників?


1
Не повна відповідь, тому коментар. Я не думаю, що ви можете розділити цю покупку на 1/4, якщо у вас немає квадрата, а прямокутника. Але те, що ти можеш зробити, якщо ти знаєш, що максимум часу, який потрібно пройти, - це обчислити окружність s і скористатися формулою s / a = v, щоб обчислити свою швидкість v.
M0rgenstern,

Відповіді:


15

Я припускаю, що ваш t переходить від 0 до 1 . (Якщо ні, просто помножте для належного масштабування.)

інтерполяція прямокутника

З’ясуйте, яка пропорція ( 0 - 1 ) кожної сторони має периметр. ( бічна довжина / загальний периметр )

Щоб знайти, скільки кожної сторони "заповнено" за час t , перебирайте сторони, віднімаючи їх пропорції, поки t не вичерпується до від'ємного значення. Це останнє ребро (яке викликало т йти негативний) заповнюються пропорцією (довжина сторони + залишається) / довжиною сторони . Решта не заповнюються.

Щоб отримати точне положення вектора при t , помножте вектор кожної сторони на пропорцію тієї сторони, яка заповнена, і додайте їх.

Це працює для будь-якого багатокутника!

довільна інтерполяція полігону


2

Синус і косинус t - відповідно координати y і x точки на колі, що утворюють кут t з віссю x. Не потрібно цього в прямокутнику! Прямокутник складається з чотирьох ліній. Якщо tйде від, 0до 1, вона досягає точки (px,py)в t==0і в (qx,qy)на t==1лінії, заданої:

(l(x),l(y)) = (t*qx + (1-t)*px, t*qy + (1-t)*py)

якщо замість 0і 1, ви час йде від t0до t1, ви можете нормалізувати час першого , а потім застосувати зазначену вище формулу.

(l(x),l(y)) = (  ((t-t0)/(t1-t0))*qx + ((t1-t)/(t1-t0))*px, ((t-t0)/(t1-t0))*qy + ((t1-t)/(t1-t0))*py  )

Тепер, для прямокутника, розділіть на чотири випадки ifпо кожному краю, який охоплює один проміжок часу, і застосуйте рух лінії.

Зауважте, що якщо ваш прямокутник вирівняний по осі, у вас завжди буде або значення x, або значення y, яке є постійним. Наприклад, для t між 0і a/4(а припустимо, що (X, Y) знаходиться внизу ліворуч),

(l(x),l(y)) = ((4*t/a)*(X+Width) + (1-4*t/a)*(X), Y+Height)

Що також дорівнює:

(l(x),l(y)) = (X + (1-4*t/a)*(Width), Y+Height)

1

Я не знаю, чи існує дійсний алгоритм для цього, але я створив його сам (Java):

int points = 4; // for a rectangle
double progress = 0.0; // 0.0 -> 1.0 (with 1.0 being 100%)
double pp = points * progress; // This calculation would otherwise be done multiple times

int p1 = Math.floor(pp);
int p2 = Math.ceil(pp);

while (p1 >= points) p1 -= points;
while (p2 >= points) p2 -= points;

double tmp = 2 * Math.PI / points;

int p1x = Math.cos(tmp * p1);
int p1y = Math.sin(tmp * p1);
int p2x = Math.cos(tmp * p2);
int p2y = Math.sin(tmp * p2);

double p = pp - Math.floor(pp);

int x = (1.0 - p) * p1x + p * p2x; // between -1.0 and 1.0
int y = (1.0 - p) * p2x + p * p2y; // between -1.0 and 1.0

if (p == 0.0) { // prevent a weird glitch when p = 0.0 (I think this is a glitch)
    x = p1x;
    y = p1y;
}

Ви повинні перетворити xі yзмінні, щоб ваша анімація була такою великою чи маленькою, як вам потрібно (множенням) і куди вам потрібно (додавання до / віднімання від x і y).

Я не перевіряв цей код, але думаю, що він повинен працювати. Це також повинно працювати для будь-якого багатокутника з будь-якою кількістю точок (ви також можете використовувати трохи коду для створення багатокутника).


1

Подано:

a=total time

perimeter = WIDTH *2 + HEIGTH * 2;

Дано час, T1як дістатися Pпо периметру (якщо припустити положення прямої у 0,0)?

T1=T1%a; //use mod to have T1<a

distT1 = (T1*Perimeter)/a; //distance traveled in time T1

тепер деяка легко первинна геометрія Scool і математика (що сподівається , що ви пожалійте мене) , щоб отримати P.xі P.yзdistT1

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.