2009-06-02 3 views
3

, 내 머리는소개 : 사각형 회전 및 하드 작업 후 피팅

내가 회전 작업 :

변수를하고있는 중이 야 (가 터키에서 오후 11시 40분입니다) .. 서비스 밝혀 :

_cx = horizontal center of rect 
_cy = vertical center of rect 
_cos = cos value of current angle 
_sin = sin value of current angle 

to rotating any point in this rect : 

function getx(x, y) 
{ 
     return _cx + _cos * (x - _cx) - _sin * (y - _cy); 
} 
function gety(x, y) 
{ 
     return _cy + _sin * (x - _cx) + _cos * (y - _cy); 
} 

원본 크기로 회전 처리하기 전에 주어진 사각형 크기를 조정하려고합니다. 어떻게해야합니까?

주셔서 감사합니다 사전

편집 : 이고르 Krivokon의 솔루션 문제는 여기 이고르 Krivokon에 의해 해결되고

모든 각도 값

var h1:Number, h2:Number, hh:Number, ww:Number, 
    degt:Number, d2r:Number, r2d:Number, deg:Number, 
    sint:Number, cost:Number; 
//@angle = given angle in radians 
//@r is source/target rectangle 
//@d2r is static PI/180 constant for degree -> radian conversation 
//@r2d is static 180/PI constant for radian -> degree conversation 
d2r = 0.017453292519943295769236907683141; 
r2d = 57.295779513082320876798154814105; 
deg = Math.abs(angle * r2d) % 360; 
if(deg < 91) 
{ 
    degt = angle; 
}else if(deg < 181){ 
    degt = (180 - deg) * d2r; 
}else if(deg < 271){ 
    degt = (deg - 180) * d2r; 
}else{ 
    degt = (360 - deg) * d2r; 
} 

sint = Math.sin(degt); 
cost = Math.cos(degt); 

h1 = r.height * r.height/(r.width * sint + r.height * cost); 
h2 = r.height * r.width/(r.width * cost + r.height * sint); 
hh = Math.min(h1, h2); 
ww = hh * r.width/r.height; 
r.x = (r.width - ww) * .5; 
r.y = (r.height - hh) * .5; 
r.height = hh; 
r.width = ww; 
을 위해 작동하는 무슨이 해당 솔루션의 수정 된 버전입니다

감사합니다.

+0

빠른 해명, 당신은 사각형 R을 가지고 있고 당신은 사각형 R을 생산하기 위해 회전 중심에 대해 그것을 확장 할 '가능한 한 R의 많은 부분을 차지합니까? –

+0

안녕하세요 Tolgahan, 적어도 사각형의 변 사이의 관계를 알지 못해도 대답 할 수 없습니다. – tekBlues

+0

예, 회전하기 전에 R을 갖고 싶습니다. –

답변

5

h와 w, 당신은 설정 각도 피입니다 원래 크기는, 새로운 높이

h1 = h*h/(w*sin(phi) + h*cos(phi)) 

h2 = h*w/(w*cos(phi) + h*sin(phi)) 

을 계산하고 HEW 높이 (H) '등을 선택하려고하면 h1과 h2 중 가장 작은 것.

그런 다음 분명히 새 폭 w' = h' * w/h입니다.

그것을 시도하십시오 - 내 수학 :) 테스트 할 시간이 없었다

+0

각도가 a => 0> = a <= 90 인 경우 수식이 괜찮습니다. 이제이 방법의 다른 변형을 시도합니다. –

+0

어떻게해야할지 모르겠지만 그 효과는 매우 좋습니다. 감사! – Budius

0

4 개의 작은 직사각형으로 칸을 나눕니다. 이것을 대각선으로 반으로 자르고 (회전 전, 모서리에서 중심점까지) 8 개의 삼각형을 갖게됩니다. 당신은 그들 중 4 명만 필요합니다. 회전 후에는이 삼각형의 빗변이 원래 경계 상자 밖으로 튀어 나와 있습니다.

빗변 (원래 각도 45도, -45도, 135도, -135도, 시작점이 mx + b이므로)이 공식을 결정하면 해당 선이 변형됩니다 (회전을 추가하여 기울기를 수정하십시오. y = 0, y = w, x = 0, x = h, 거리 공식, 무한 경우에 대한 테스트) 경계선과 해당 선을 교차하십시오. & 구배가 가장 짧은 것 (구석에 벽 중앙) . 모든 빗변이 처음부터 같은 길이 였으므로,이 모든 값을이 새 값으로 크기를 조정하면 새로운 사각형이 생깁니다.

내가 제대로하고 있습니까?

+0

나는 쉬운 방법이 있어야한다고 생각한다. –

+0

나는 그것을 어떻게 표현할 수 있었는지 상상할 수 없다. "가장 멀리 튀어 나와있는 구석이 튀어 나와서 크기를 재조정한다. " – ryansstack

0
function resize_factor() 
{ 
    /* Find how far the upper-left corner sticks up beyond the top */ 
    overtop = gety(0, 0); 
    /* Compute a vertical resize factor that would put that point at the top */ 
    /* (be sure to use floating point arithmetic) */ 
    vertical_resize = _cy/(_cy - overtop); 

    /* Do the same for the lower-left corner sticking out beyond the left */ 
    /* (using 2*_cy for the height of the rectangle) */ 
    overleft = getx(0, 2*_cy);  
    horizontal_resize = _cx/(_cx - overleft); 

    /* Return whichever resize constraint is stricter */ 
    return min(vertical_resize, horizontal_resize); 
} 

function resize_x(x) 
{ 
    /* To get location of a point, after resize, before rotation... */ 
    /* ...multiply its resize factor by its distance from the center. */ 
    return resize_factor()*(x - _cx) + _cx; 
} 

function resize_y(y) 
{ 
    return resize_factor()*(y - _cy) + _cy; 
} 

/* These resized coordinates can be used inside any other code you want: */ 
function getx_after_resize_and_rotate(x, y) 
{ 
    return getx(resized_x(x), resized_y(y)); 
} 

참고 :이 코드는 시계 방향이 시계 방향으로 90도 회전하지 않는다고 가정합니다 (사진의 표시 내용이기 때문에). 각도가 다른 경우라면 네 모서리를 모두 확인하고 어느 것이 가장 멀리 겹쳐지고 겹쳐져 있는지 확인해야 할 것입니다.

0
fitRect: function(rw,rh,radians){ 
      var x1 = -rw/2, 
       x2 = rw/2, 
       x3 = rw/2, 
       x4 = -rw/2, 
       y1 = rh/2, 
       y2 = rh/2, 
       y3 = -rh/2, 
       y4 = -rh/2; 

      var x11 = x1 * Math.cos(radians) + y1 * Math.sin(radians), 
       y11 = -x1 * Math.sin(radians) + y1 * Math.cos(radians), 
       x21 = x2 * Math.cos(radians) + y2 * Math.sin(radians), 
       y21 = -x2 * Math.sin(radians) + y2 * Math.cos(radians), 
       x31 = x3 * Math.cos(radians) + y3 * Math.sin(radians), 
       y31 = -x3 * Math.sin(radians) + y3 * Math.cos(radians), 
       x41 = x4 * Math.cos(radians) + y4 * Math.sin(radians), 
       y41 = -x4 * Math.sin(radians) + y4 * Math.cos(radians); 

      var x_min = Math.min(x11,x21,x31,x41), 
       x_max = Math.max(x11,x21,x31,x41); 

      var y_min = Math.min(y11,y21,y31,y41); 
       y_max = Math.max(y11,y21,y31,y41); 

      return [x_max-x_min,y_max-y_min]; 
     }