IT이야기

특정 지점을 중심으로 정점을 회전하는 방법

cyworld 2021. 4. 27. 21:55
반응형

특정 지점을 중심으로 정점을 회전하는 방법은 무엇입니까?


2D 공간에 두 개의 점이 있고이 점 중 하나를 X도 회전하고 다른 점이 중심 역할을한다고 가정합니다.

float distX = Math.abs( centerX -point2X );
float distY = Math.abs( centerY -point2Y );

float dist = FloatMath.sqrt( distX*distX + distY*distY );

지금까지 두 점 사이의 거리를 찾아야했습니다 ... 그 점에서 어디로 가야할지 아이디어가 있습니까?

여기에 이미지 설명 입력


가장 쉬운 방법은 세 가지 변환을 구성하는 것입니다.

  1. 점 1을 원점으로 가져 오는 번역
  2. 필요한 각도만큼 원점을 중심으로 회전
  3. 포인트 1을 원래 위치로 되 돌리는 번역

이 모든 작업을 수행하면 다음과 같은 변형으로 끝납니다.

newX = centerX + (point2x-centerX)*Math.cos(x) - (point2y-centerY)*Math.sin(x);

newY = centerY + (point2x-centerX)*Math.sin(x) + (point2y-centerY)*Math.cos(x);

이것은 x시계 방향 회전 ( 좌표계의 표준 또는 오른손 방향)에 대해 각도 가 음수 라고 가정합니다 . 그렇지 않은 경우 sin(x).


2 차원 회전 매트릭스가 필요합니다. http://en.wikipedia.org/wiki/Rotation_matrix

당신의 새로운 포인트는

 newX = centerX + ( cosX * (point2X-centerX) + sinX * (point2Y -centerY))
 newY = centerY + ( -sinX * (point2X-centerX) + cosX * (point2Y -centerY))

시계 반대 방향이 아닌 시계 방향으로 회전하기 때문에


Java Graphics2D API를 사용한다고 가정하고 다음 코드를 시도하십시오.

    Point2D result = new Point2D.Double();
    AffineTransform rotation = new AffineTransform();
    double angleInRadians = (angle * Math.PI / 180);
    rotation.rotate(angleInRadians, pivot.getX(), pivot.getY());
    rotation.transform(point, result);
    return result;

피벗은 회전하는 지점입니다.


  1. "1"을 0,0으로 번역

  2. 회전

    x = sin (각도) * r; y = cos (각도) * r;

  3. 다시 번역


2D의 다른 점을 중심으로 점을 회전하는 방법은 다음과 같습니다. 3D에서 이것은 z 축에 대한 회전으로 사용될 수 있습니다. 점의 z- 좌표는 변경되지 않기 때문에 입력됩니다. 3D에서 x 축과 y 축에 대한 회전도 쉽게 구현할 수 있습니다.

코드는 JavaScript로되어 있습니다. 시작 부분에 주석 처리 된 줄은 함수에 대한 테스트 세트입니다. 또한 사용의 예가됩니다.

//A = new Array(0,0)
//S = new Array(-1,0)
//fi = 90
//alert("rotujBod: " + rotatePoint(A, S, fi))

function rotatePoint(A, S, fi) {
/** IN points A - rotated point, S - centre, fi - angle of rotation (rad)
*    points in format  [Ax, Ay, Az], angle fi (float)
*       OUT point B
*/
    r = Math.sqrt((A[0] - S[0])*(A[0] - S[0]) + (A[1] - S[1])*(A[1] - S[1]))
    originOfRotation = new Array(S[0] + r, S[1])
    if (A[1] < S[1]) {
        A2 = new Array(A[0], -1*A[1])
        originalAngle = -1*sizeOfAngle(originOfRotation, S, A2)
    } else {
    originalAngle = sizeOfAngle(originOfRotation, S, A)
    }
    x = S[0] + r*Math.cos(fi + originalAngle)
    y = S[1] + r*Math.sin(fi + originalAngle)
    B = new Array(x, y)
    return(B)
}

function sizeOfAngle(A, S, B) {
    ux = A[0] - S[0]
    uy = A[1] - S[1]
    vx = B[0] - S[0]
    vy = B[1] - S[1]
    if((Math.sqrt(ux*ux + uy*uy)*Math.sqrt(vx*vx + vy*vy)) == 0) {return 0}
    return Math.acos((ux*vx + uy*vy)/(Math.sqrt(ux*ux + uy*uy)*Math.sqrt(vx*vx + vy*vy)))
}

여기에 회전 방향을 신경 쓰는 버전이 있습니다. 오른쪽 (시계 방향)은 음수이고 왼쪽 (시계 반대 방향)은 양수입니다. 점 또는 2D 벡터를 보내고이 메서드 (마지막 줄)에서 기본 요소를 설정하여 성능을위한 메모리 할당을 피할 수 있습니다. vector2 및 mathutils를 사용하는 라이브러리 또는 java의 내장 포인트 클래스로 대체해야 할 수 있으며 mathutils 대신 math.toradians ()를 사용할 수 있습니다.

/**
 * rotates the point around a center and returns the new point
 * @param cx x coordinate of the center
 * @param cy y coordinate of the center
 * @param angle in degrees (sign determines the direction + is counter-clockwise - is clockwise)
 * @param px x coordinate of point to rotate 
 * @param py y coordinate of point to rotate 
 * */

public static Vector2 rotate_point(float cx,float cy,float angle,float px,float py){
    float absangl=Math.abs(angle);
    float s = MathUtils.sin(absangl * MathUtils.degreesToRadians);
    float c = MathUtils.cos(absangl * MathUtils.degreesToRadians);

    // translate point back to origin:
    px -= cx;
    py -= cy;

    // rotate point
    float xnew;
    float ynew;
    if (angle > 0) {
        xnew = px * c - py * s;
        ynew = px * s + py * c;
    }
    else {
        xnew = px * c + py * s;
        ynew = -px * s + py * c;
    }

    // translate point back:
    px = xnew + cx;
    py = ynew + cy;
    return new Vector2(px, py);
}

이 방법은 게시물에서 시도한 방법보다 더 많은 성능을 제공합니다. 매우 비용이 많이 드는 sqrt를 사용하기 때문에 이런 식으로 각도에서 라디안으로 변환하여 룩업 테이블로 관리하기 때문입니다. 그래서 그것은 매우 높은 성능을 가지고 있습니다.

참조 URL : https://stackoverflow.com/questions/12161277/how-to-rotate-a-vertex-around-a-certain-point

반응형