Russian Qt Forum
Октябрь 01, 2024, 02:29 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Программа типа xEyes  (Прочитано 4426 раз)
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« : Июль 17, 2013, 20:40 »

Всем здрасти Улыбающийся
Захотелось вот сделать такую и вроде бы почти все сделал, а вот как ограничить позицию "зрачка", чтобы из "глаза" не убежал я не могу допереть Улыбающийся

Вполне получилось узнавать, когда "зрачок" выходит за пределы "глаза", а вот как вернуть его не особо могу придумать Непонимающий

Помогите Улыбающийся

Код:

h.
Код:
#include <QtGui>
#include <QtCore>

class UEyes: public QWidget
{
    Q_OBJECT
    
public:
    UEyes(QWidget *parent = 0);

private:
    QPoint globalPosCursor;

protected:
    virtual void timerEvent(QTimerEvent *);
    virtual void paintEvent(QPaintEvent *);
};

cpp
Код:
/// PUBLIC
UEyes::UEyes(QWidget *parent)
    : QWidget(parent)
{
    startTimer(20);
}

///PROTECTED
void UEyes::timerEvent(QTimerEvent *)
{
    globalPosCursor = QCursor::pos();
    update();
}

void UEyes::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);

    // рисуем фон
    painter.setBrush(Qt::white);
    painter.setPen(Qt::NoPen);

    painter.drawRect(rect());
    // рисуем фон


    QPoint pos = mapFromGlobal(globalPosCursor);

    int widthLeft = width() / 2;
    int heightLeft = height() / 2;

    
    // рисуем глаз
    painter.setBrush(Qt::white);
    painter.setPen(QPen(Qt::black, 3.0));

    QPoint posLeftEye = QPoint(widthLeft, heightLeft);
    int radiusEye = 40;
    
    painter.drawEllipse(posLeftEye, radiusEye, radiusEye);
    // рисуем глаз


    QPoint posLeftPupil = pos;

    int radiusPupil = 10;
    int x1 = posLeftEye.x();
    int y1 = posLeftEye.y();

    int x2 = posLeftPupil.x();
    int y2 = posLeftPupil.y();

    if(pow(abs(x1 - x2), 2) + pow(abs(y1 - y2), 2)
            <= pow(radiusEye, 2) - pow(radiusEye - radiusPupil, 2))
    {
        qDebug() << "внутри";
    }else
    {
        qDebug() << "вне";
    }

    // рисуем зрачок
    painter.setBrush(Qt::black);
    painter.setPen(Qt::NoPen);
    painter.drawEllipse(posLeftPupil, radiusPupil, radiusPupil);
    // рисуем зрачок

    
    painter.setPen(QPen(Qt::green, 1.5));
    painter.drawLine(QPoint(widthLeft, heightLeft), pos);
}
« Последнее редактирование: Июль 17, 2013, 22:22 от gil9red » Записан

Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #1 : Июль 17, 2013, 21:13 »

Создайте простенькую мат модель. Проще всего считать что центр глаза в точке (xe, ye, 0), а мыша в позиции (xm, ym, h) - эту высоту h Вы подберете. Тогда имеете вектор глаз - точка. Вычисляете угол этого вектор с осью Z, нормируете и получаете центр вписанного зрачка
Записан
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #2 : Июль 17, 2013, 21:39 »

Зачем ось Z в двухмерной плоскости Непонимающий

Я вот такое делаю:
Записан

gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #3 : Июль 18, 2013, 00:55 »

Проблему решил:
Сделал отрисовку от центра глаза к курсору линию и проверял в каком месте она пересекалась с окружностью ("глазом")

Записан

Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #4 : Июль 18, 2013, 11:02 »

Сделал отрисовку от центра глаза к курсору линию и проверял в каком месте она пересекалась с окружностью ("глазом")
А на каком расстоянии (от центра глаза) Вы рисуете зрачок?
Записан
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #5 : Июль 18, 2013, 15:33 »

Расстояние от центра на прямую зависит от того, где в данный момент находится курсор мыши )
Но чтобы, "зрачок" не ушел вне "глаза" приходится делать проверку, и если он вышел за пределы, вернуть его к границе глаза Улыбающийся

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

На изображении показано определение куда вернуть "зрачок"

PS. Выложил исходный код. В нем сделан только 1 глаз с зрачком, но добавить 1-n глаз не так будет сложно  Смеющийся
PSS. Не люблю подобные задачки, но вроде бы "первый блин не получился комом" Улыбающийся
PSSS. Комментарии к функции isIntersectionEllipseAndDirect не мои Веселый Нашел функцию где то в инете - не помню где было (писал и гуглил ночью, когда очень хотелось добить алгоритм), в ней изменил название, интерфейс и упросил реализацию, остальное не трогал Улыбающийся
« Последнее редактирование: Июль 18, 2013, 15:44 от gil9red » Записан

Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Июль 18, 2013, 16:33 »

PSSS. Комментарии к функции isIntersectionEllipseAndDirect не мои Веселый Нашел функцию где то в инете - не помню где было (писал и гуглил ночью, когда очень хотелось добить алгоритм), в ней изменил название, интерфейс и упросил реализацию, остальное не трогал Улыбающийся
Да, комментарии заслуживют цитаты
Цитировать
// функция которая счетает пересиченния еллипса и прямой
// когда пересечений нету возврасчает false иначе true и
// в масив Res присваевается точки пересичение
Свое решение было бы куда проще чем найденный кусок кала. Вам ведь нужно найти не любое пересечение (общий случай), а пересечение с прямой проходящей через центр эллипса, точнее даже радиус в данном напрвлении. Каноническое уравнение эллипса

(x * x) / (a * a) + (y * y) / (b * b) = 1;  // где a и b - полуоси эллипса

Подставляя y = кх получаете квадратное уравнение, находите корни как учили в 6-м классе

Понятно что зрачок "в пределах" но все же неясно, на каком расстоянии от центра? Всегда на максимально возможном? Тогда можно лучше сделать (если надо)
Записан
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #7 : Июль 18, 2013, 17:01 »

Ясно Улыбающийся
Записан

gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #8 : Июль 18, 2013, 21:26 »

Прикалывает меня это Веселый
« Последнее редактирование: Июль 19, 2013, 04:55 от gil9red » Записан

Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.049 секунд. Запросов: 23.