Устранить эффект перекоса в комбинированных трек и зум - PullRequest
0 голосов
/ 10 января 2019

Я пишу для HTML5 Canvas, используя его в качестве окна просмотра, в котором я поддерживаю центральный источник и уровень масштабирования. Я хочу отслеживать и масштабировать регион, но столкнулся с естественным эффектом, который портит внешний вид, который я пытаюсь получить. Этот вопрос касается того, как я могу смягчить это, сохраняя естественный эффект.

Представьте, что у меня на потолке установлена ​​направленная вниз камера, а где-то на полу лежит лист бумаги. Я перемещаю камеру с постоянной скоростью вдоль потолка, пока она не окажется над бумагой, в то же время увеличивая масштаб с линейной скоростью, чтобы бумага в конечном итоге заполнила визуализированное изображение. Эти действия происходят одновременно.

При этом можно наблюдать эффект, при котором бумага соскальзывает с рамки, прежде чем она возвращается в центр. Вероятно, это лучше всего объяснить визуально и сохранить в двух измерениях:

img

Это нехорошо. Рассмотрим пользователя, который просит сосредоточиться на чем-то. Их концептуализация заключается в том, что сущность движется в поле зрения, и странно, что она, кажется, сначала удаляется, прежде чем приблизится.

Эффект, который я хочу получить, заключается в том, что целевой объект только приближается к центру кадра и никогда не отступает. Полагаю, ответ заключается в том, чтобы как-то исказить скорость увеличения (или скорость движения, хотя я бы не предпочел этого), предположительно, в зависимости от задействованных расстояний или искусственного изменения масштаба, чтобы страница сохранялась в рамке. Я бы предпочел помощь в поиске решения в соответствии с прежним подходом.


Обновление:

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

Это интуитивно кажется лучше, но у меня все еще есть две проблемы. Несомненно, я могу найти уравнение для d при t , но мое исчисление слабое, и я мог бы закончить выборку для максимума, а не получить обратную функцию для ее поиска, что и является Я бы действительно предпочел. Я также не уверен, как выбирать между двумя максимумами для определения граничного времени (хотя может быть, что нет «правильного» ответа на этот вопрос, и это меньше беспокоит меня). Любая помощь по любой проблеме, или любое другое понимание более широкой проблемы, будет очень благодарна.

1 Ответ

0 голосов
/ 11 января 2019

Ой, так что у вас есть реализация SW без камеры HW ...

Я имел в виду реальный эффект перекоса на английском языке, называемый Рулонный затвор : если вы получаете изображение, перемещая реальную камеру сканирования HW (без TDI технология ) затем появляется эффект перекоса + размытия, скользящий по линиям сканирования ... попробуйте сделать фотографию из бокового окна движущегося автомобиля, изображение будет искажено.

Эффект , который вы описываете , не имеет ничего общего с перекосом, это просто математическая «особенность», извините, у меня нет имени для него.

Поскольку ваша камера SW , только вы можете влиять на панорамирование и масштабирование по своему вкусу, поэтому я просто вычислю zoom с камеры FOV и pan. Я вижу это так:

overview

Итак:

 I. a = FOV / zoom
II. tan(0.5*a) = (x1-x0) / h
------------------------
zoom = 0.5*FOV/atan( (x1-x0) / h )

Где h - высота потолка, x0 - положение камеры (панорамирования), x0 - положение края бумаги, а FOV - поле обзора вашей камеры без увеличения ...

[edit1] вставка бумаги и анимация ...

Я закончил с этим:

animation

Здесь код C ++ / VCL для этого:

//---------------------------------------------------------------------------
double x0,x1,w=50,h=200,FOVx=60.0*M_PI/180.0,zoom,pan;
double t=0; // animation parameter <0,1>
//---------------------------------------------------------------------------
void TMain::draw()
    {
    if (!_redraw) return;

    // clear buffer
    bmp->Canvas->Brush->Color=clBlack;
    bmp->Canvas->FillRect(TRect(0,0,xs,ys));

    double y0,y1,dx;

    // position side view onto screen based on its size xs,ys
    y0=0.5*(ys-h);
    y1=y0+h;
    x0=0.5*xs;
    x1=x0+(h*tan(0.5*FOVx));
    // compute zoom,pan from t
    pan=(x1-x0+(0.5*w))*t;
    zoom=0.5*FOVx/atan(((1.0-t)*(x1-x0)+(0.5*w*t))/h);
    // scene
    bmp->Canvas->Pen->Color=clBlue;
    bmp->Canvas->MoveTo( 0,y0);
    bmp->Canvas->LineTo(xs,y0);
    bmp->Canvas->MoveTo( 0,y1);
    bmp->Canvas->LineTo(xs,y1);
    // paper
    bmp->Canvas->Pen->Color=clRed;
    bmp->Canvas->MoveTo(x1,y1);
    bmp->Canvas->LineTo(x1+w,y1);
    // FOVx
    dx=h*tan(0.5*FOVx/zoom);
    bmp->Canvas->Pen->Color=clAqua;
    bmp->Canvas->MoveTo(x0+pan-dx,y1);
    bmp->Canvas->LineTo(x0+pan,y0);
    bmp->Canvas->LineTo(x0+pan+dx,y1);
    // points
    dx=4;
    bmp->Canvas->Pen->Color=clAqua;
    bmp->Canvas->Brush->Color=clBlue;
    bmp->Canvas->Ellipse(x0-dx,y0-dx,x0+dx,y0+dx);
    bmp->Canvas->Ellipse(x0+pan-dx,y0-dx,x0+pan+dx,y0+dx);
    bmp->Canvas->Ellipse(x1-dx,y1-dx,x1+dx,y1+dx);
    bmp->Canvas->Font->Color=clYellow;
    bmp->Canvas->Brush->Style=bsClear;
    bmp->Canvas->TextOutA(x0,y0-20,"x0");
    bmp->Canvas->TextOutA(x0+pan+20,y0+5,"x0+pan");
    bmp->Canvas->TextOutA(x1,y1+5,"x1");
    bmp->Canvas->Brush->Style=bsSolid;

    // render backbuffer
    Main->Canvas->Draw(0,0,bmp);
    _redraw=false;
    }
//---------------------------------------------------------------------------

Если вы игнорируете рендеринг, вот что для вас важно:

pan=(x1-x0+(0.5*w))*t;
zoom=0.5*FOVx/atan(((1.0-t)*(x1-x0)+(0.5*w*t))/h);

Таким образом, я немного изменил значение x1 (это другой край бумаги) и вместо x1 в исходных уравнениях, приведенных выше, я использовал x1+w*t, что означает, что бумага не видна в начале (t=0), но это касается его снаружи, и оно полностью видно, когда (t=1). Остальное только результат замещения ...

w - это ширина бумаги, t=<0.0,1.0> - это параметр анимации, а все остальные значения не меняли значения ...

Анимация просто увеличивает t на 0.02 в таймере 150 мс, записанном моим GIF-кодером (вот почему он такой прерывистый)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...