Java 2D - перетащите мышь, чтобы плавно повернуть изображение - PullRequest
3 голосов
/ 04 февраля 2010

Какая логика заключается в повороте изображения движением мыши. Я знаю, как вращаться, используя graphics2d.rotate ... но с трудом справляюсь с мышью в качестве источника вращения. Вот основные шаги:

  1. получить расстояние мыши x (dx) и мыши y (dy) от точки привязки (в этом случае это будет центр изображения, которое мы хотим повернуть).
  2. используйте эту точку в Math.arcTan2 (dy, dx) для получения угла или поворота.
  3. используйте значение от шага к методу Graphics2D.rotate.

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

Вот часть кода:

// mouse dragged events get sent here.
public void mouseDragged( MouseEvent e ) {
    int mx = e.getX( ), my = e.getY( );
    // just checking if it falls within bounds of the image we 
    // want to rotate.
    if( mx > speedKX || mx < speedKX + speedK.getWidth( ) || my > speedKY || my < speedKY + speedK.getHeight( )/2 )
    {
        theta += getTheta( e.getX( ), e.getY( ) ); 
    }
} 

1 Ответ

4 голосов
/ 04 февраля 2010

Как я понимаю, вы должны искать начальный угол (когда вы нажимаете, линию между якорем и вашим щелчком) и текущий угол (когда вы перетаскиваете, та же линия).Этот угол (независимо от текущего расстояния до точки привязки) даст вам вращение.

Так что вам нужно:

rotate(anglenow - angle0)

Как его найти:

ВВ обоих случаях (начальный щелчок и событие перемещения мыши) необходимо найти угол между якорем и точкой мыши, считая якорь источником.

Я бы использовал метод (getAngle (x1, y1, x2, y2).Этот метод (за исключением условий гонки, таких как тот же самый x или тот же самый y, легко обнаруживаемый) должен вычислять arctan (dy / dx).

Знак

Но когда вы делитеdy / dx это может быть:

+ / + -> +
+ / - -> -
- / + -> -
- / - -> +

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

Я должен рассмотреть arctandoc или source, чтобы увидеть, какие значения он дает (между 0 и pi, или -pi / 2 и + pi / 2) и затем проверить знак dx или dy (в зависимости от того, какой диапазон возвращает arctan) и использовать его для добавления /уменьшите число pi до полученного угла.

Тогда вы получите метод getAngle, который возвращаетn правильно на 360º.

Edit

Javadoc говорит:

Math.atan перенастраивает арктангенс угла в диапазоне -от pi / 2 до pi / 2.

Итак, если предположить, что ваш угол значения 0 соответствует оси X, как я и предполагал, диапазон, который он возвращает, является правым полушарием.Таким образом, вы должны отделить правое полушарие от левого.

Если вы вычислите dx = xtarget - xorigin (как вы делали для деления), то оно будет положительным, если правильное полушарие правильное, и отрицательнымесли это не так.

Так что, если dy <0, то вы должны добавить пи к полученному углу.Это будет между -pi / 2 и 3pi / 2.Вы также можете исправить результат, передав все в диапазон (-pi, pi) или (0,2pi). </p>

Редактировать: псевдокод, пожалуйста, проверьте еще раз!

onmousedown {
    startpoint = (x,y);
    startangle = getAngle(origin, startpoint);
}

onmousemove {
    currentpoint = (x,y);
    currentangle = getAngle(origin, currentpoint);
    originalimage.rotate(currentangle - startangle);
}

getAngle(origin, other) {
    dy = other.y - origin.y;
    dx = other.x - origin.x;
    if (dx == 0) // special case
        angle = dy >= 0? PI/2: -PI/2;
    else
    {
        angle = Math.atan(dy/dx);
        if (dx < 0) // hemisphere correction
            angle += PI;
    }
    // all between 0 and 2PI
    if (angle < 0) // between -PI/2 and 0
        angle += 2*PI;
    return angle;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...