Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: 6460
Последний выпуск: 19.06.2015

Поиск пересечения точки и повернутого прямоугольника

7.0K
24 декабря 2009 года
pink master
79 / / 21.10.2006
Решил запрограммировать (на java) Free Transform как в Photoshop'е для прямоугольника.
То есть его можно мышкой перемещать, изменять размер и вертеть.
Сначала я реализовал перемещение прямоугольника. Тут все получилось.
Самый интересный момент - определение когда мышка наведена на повернутый на N градусов прямоугольник.
Для этого я написал функцию containsRotated(Point p), которая определяет внутри ли повернутого прямоугольника точка или нет.
Ее основной смысл что коллизия ищется для прямоугольника вдоль осей ХY, а сдвигается только точка. Поясню на картинке.
См вложение "pic1.jpg"
(То есть пользователь видит только черный прямоугольник и красный клик, а на самом деле сравнивается серый и зеленый)
Она выглядит так.
Код:
public boolean containsRotated(Point p) {
        // deltaA is diff between X-axe and vector to NW-point.
        double deltaX = p.x - x;
        double deltaY = p.y - y;
        double deltaA = Math.atan2(deltaY, deltaX);
       
        double raduis = Point2D.distance(x, y, p.x, p.y);
        double pointRotAngle = deltaA - r;
       
        int rotatedX = (int)(x + raduis*Math.cos(pointRotAngle));
        int rotatedY = (int)(y + raduis*Math.sin(pointRotAngle));
        Point rotatedPoint = new Point(rotatedX, rotatedY);
       
        setBounds(x,y,w,h);
        return contains(new Point(rotatedPoint.x - x, rotatedPoint.y - y));

    }

Дальше решил реализовать скейл, для этого хотел использовать ту же функцию когда мышка не внутри самого прямоугольника, но внутри прямоугольника который на 10 пикселов больше.
См вложение "pic2.jpg"
Но почему-то простое изменение размера входного прямоугольника работает не правильно.
 
Код:
public boolean containsRotated(Point p, int offset) {
        int x = this.x - offset;
        int y = this.y - offset;
        int w = this.w + offset*2;
        int h = this.h + offset*2;

                --||--

    }

Хотя та же функция работает правильно при перемещении любых прямоугольников.
Может кто видит ошибку, или она вообще не тут?
Код проекта для эклипса и просто код приложены.
Если кто-нибудь бы помог разобраться то я был бы очень благодарен.
494
25 декабря 2009 года
Jail
550 / / 30.01.2007
Бегло просмотрел код. Не ротайтится ваш прямоугольник это да и помоему проблема в методе
 
Код:
public void mouseDragged(MouseEvent e) {}
когда вы дрогаете и пытаетесь сделать repaint компонента.
код какой-то немного низкоуровневый. задался вопросом, почему вы не используете
Цитата:
[COLOR=#000000]java.awt.geom.AffineTransform;
[/COLOR][COLOR=#000000]java.awt.geom.Rectangle2D;[/COLOR]

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

7.0K
26 декабря 2009 года
pink master
79 / / 21.10.2006
Спасибо за ответ и спасибо за пример,
я правда уже и сам справился. Дело было в том что я пытался вращать описывающий прямоугольник всегда вокруг точки (х - оффсет, y - оффсет), а это правильно только для вращения с нулевым градусом.
Сейчас исправил.

Я что-то и сам не знаю почему не использую java.awt.geom.AffineTransform. Аааа!, я думал что AffineTransform только для Grapohics2d работает. А обычный прямоугольник нельзя. Походу я был неправ^^
Приду домой посмотрю ваш пример обязательно.



> Да и еще одно замечание. когда курсор в вашем примере наведен на область с которой мужно дрогать, с любой стороны прямоугольника устанавливается один и тот же курсор - для дроганья вниз.
Это да, так у меня там вчера целая таблица получилась - при вращении то все меняется. Уже реализовано. Буду вот сегодня рисайз делать, вчера до 4х ночи сидел^^ И походу надо переписать с АffineTransform, чтоб код понятней был. Еще раз спасибо.
Если интересно могу выложить исходники.
7.0K
26 декабря 2009 года
pink master
79 / / 21.10.2006
Посмотрел текст вашего примера, так там тоже вращается Graphics.
 
Код:
g2.draw(square);
    g2.transform(t);

А мне бы такой метод, который применяет трансформацию к прямоугольнику и возвращает тоже повернутый прямоугольник. А то для рисования то это достаточно, а для определения пересечения нужны уже реальные повернутые координаты. Иначе как я узнаю когда мышка рядом с повернутым на 45 ректом?
494
27 декабря 2009 года
Jail
550 / / 30.01.2007
Цитата: pink master
Посмотрел текст вашего примера, так там тоже вращается Graphics.
А мне бы такой метод, который применяет трансформацию к прямоугольнику и возвращает тоже повернутый прямоугольник. А то для рисования то это достаточно, а для определения пересечения нужны уже реальные повернутые координаты. Иначе как я узнаю когда мышка рядом с повернутым на 45 ректом?


Дак без вращения с Graphics это достаточно рутинная операция и код получается низкоуровневым и сложно читаемым. а потом представьте, что решите расширить свой пример и внедрить в продакшен аппликацию. поддерка версионности и поик ошибок превратиться просто в кошмар.
Для определения реальных координат ректа нет никакой проблемы. ну к примеру:

 
Код:
//Adjustments to put component to at the cursor's tip.
    private static final int XFUDGE = 40;
    private static final int YFUDGE = 57;

//Make component follow the cursor.
    public void mouseMoved(MouseEvent e) {
        someComponent.setLocation(e.getX()-XFUDGE, e.getY()-YFUDGE);
    }
Это грубый пример, но смысл в том, что бы хранить некоторое смешение от местоположения курсора и самого компонента. так же можно хранить protected переменную(ые) класса для определения местоположения вашего ректа при вращении. надеюсь я вас правильно понял.
А использование [COLOR=#000000]AffineTransform[/COLOR][COLOR=#000000] & Rectangle2D[/COLOR] думаю крайне необходимо для читабельности, поддерки в будующем версионности вашего проекта да и стандартный класс в jdk думаю написан лучше, чем вы сможете реализовать что-то самостоятельно :)
Если есть желание, то выложите ваш пример, переписанный с [COLOR=#000000]AffineTransform[/COLOR][COLOR=#000000] & Rectangle2D. другим будет полезно. а лучше еще закиньте его в раздел "Мои исходники" в вашем аккаунте.
Ну и дам возможно полезную подсказку - некоторые куски кода можно найти через [/COLOR]codefetch. Бывает крайне полезно.

Знаете кого-то, кто может ответить? Поделитесь с ним ссылкой.

Ваш ответ

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог