2014-06-18 3 views
0

Windows에서 각도를 사용하여 사각형을 그려야한다고 가정 해 봅시다.TranslateTransform 이후 최대 사용 가능한 면적을 계산하십시오.

나는

private void Form1_Paint(object sender, PaintEventArgs e) 
    { 
     e.Graphics.RotateTransform(20); 
     e.Graphics.DrawRectangle(Pens.Black, 0, 0, e.ClipRectangle.Width, e.ClipRectangle.Height); 
    } 

하여이 작업을 수행 할 수 있지만이 사각형 따라서 왼쪽과 아래 부분이 누락 된 회전 불과합니다.

result

는하지만 정말 실현하려 싶은 것은 내가 할 수있는 최선의 방법을 무엇이

what I want to achive

같은 내 양식 내부의 특정 각도와 가장 큰 가능한 사각형을 그리 할 것입니다 이?

답변

0

모든 4면에 닿는 각도 θ의 직사각형을 찾을 수있다. W, H를 우리 창의 너비와 높이라고하면, 미리 알고있는 라디안 단위의 각도입니다. 이제 우리가 상자에 넣으려고하는 사각형의 너비와 높이를 a, b라고하면, 우리가 찾고자하는 두 값입니다. x0, y0는 윈도우 x0 = W/2, y0 = H/2의 중심에있는 점의 좌표이다. 사각형 모서리 중 하나는

x1 = x0 - 0.5 * a * sin(th) + 0.5 * b * cos(th) 
y1 = y0 + 0.5 * a * cos(th) + 0.5 * b * sin(th) 

다른 점은 다른 기호와 유사합니다. 약간의 삼각법이이를 나타낼 것입니다. 직사각형 측면을 터치 들어

우리는이 우리에게 우리가 해결할 수있는 연립 방정식의 쌍을 제공

a * sin(th) + b cos(th) = W 
a * cos(th) + b sin(th) = H 

합니다.COS (일) COS (일 - 죄 (회) 및 COS ​​의해 제 2 (일)

a * sin(th) sin(th) + b cos(th) sin(th) = W sin(th) 
a * cos(th) cos(th) + b sin(th) cos(th) = H cos(th) 

빼기

a (sin(th) sin(th) - cos(th) cos(th)) = W sin(th) - H cos(th) 

분할기 (SIN (일) 죄 (번째)에 의해 제 곱)) 범

a = (W sin(th) - H cos(th))/(sin(th) sin(th) - cos(th) cos(th)) 

유사한 프로세스

b = (H sin(th) - W cos(th))/(sin(th) sin(th) - cos(th) cos(th)) 

준다 일단 a와 b를 얻으면 직사각형의 모서리를 계산하고 그릴 수 있습니다.

가 나는 jsfiddle http://jsfiddle.net/SalixAlba/5jcT7/에 코드를 삽입 한 코드는 두 가지 측면을 만지지 큰 일이있을 수 있으므로이 반드시 가장 큰 사각형을 제공하지 않습니다

// canvas and mousedown related variables 
var canvas = document.getElementById("canvas"); 
var ctx = canvas.getContext("2d"); 
var $canvas = $("#canvas"); 
var canvasOffset = $canvas.offset(); 
var offsetX = canvasOffset.left; 
var offsetY = canvasOffset.top; 
var scrollX = $canvas.scrollLeft(); 
var scrollY = $canvas.scrollTop(); 
// save canvas size to vars b/ they're used often 
var W = canvas.width; 
var H = canvas.height; 

var spinner = $("#startAng").spinner({ 
    spin: function(event, ui) { 
    if (ui.value > 180) { 
     $(this).spinner("value", ui.value - 360); 
     draw(); 
     return false; 
    } else if (ui.value < -180) { 
     $(this).spinner("value", ui.value + 360); 
     draw(); 
     return false; 
    } 
    draw(); 
    } 
}); 


var angle = 10.0; 

function draw() { 
ctx.clearRect(0, 0, canvas.width, canvas.height); 
angle = $("#startAng").spinner("value"); 
var th = Math.PI*angle/180.0; 
var S = Math.sin(th); 
var C = Math.cos(th); 
var S2 = S*S - C*C; 
var a = (W*S-H*C)/S2; 
var b = (H*S-W*C)/S2; 
var x0 = W/2; 
var y0 = H/2; 
//alert("angle "+angle+"S "+S+" "+C+" "+a+" "+b); 
var x1 = x0 - 0.5 * a * Math.sin(th) + 0.5 * b * Math.cos(th); 
var y1 = y0 + 0.5 * a * Math.cos(th) + 0.5 * b * Math.sin(th); 

var x2 = x0 - 0.5 * a * Math.sin(th) - 0.5 * b * Math.cos(th); 
var y2 = y0 + 0.5 * a * Math.cos(th) - 0.5 * b * Math.sin(th); 

var x3 = x0 + 0.5 * a * Math.sin(th) + 0.5 * b * Math.cos(th); 
var y3 = y0 - 0.5 * a * Math.cos(th) + 0.5 * b * Math.sin(th); 

var x4 = x0 + 0.5 * a * Math.sin(th) - 0.5 * b * Math.cos(th); 
var y4 = y0 - 0.5 * a * Math.cos(th) - 0.5 * b * Math.sin(th); 

ctx.beginPath(); 
ctx.moveTo(x1,y1); 
ctx.lineTo(x2,y2); 
ctx.lineTo(x4,y4); 
ctx.lineTo(x3,y3); 
ctx.lineTo(x1,y1); 
ctx.closePath(); 
ctx.stroke(); 
} 

$(".ui-spinner-input").on("spinchange", draw); 
$(".ui-spinner-input").on("spinstop", draw); 
$("#baseRad").on("spin", draw); 

draw(); 

주이며, 또한 몇 가지 한계에있다 가능한 각도.

0

이 문제를 해결하기 위해 일부 스케치를했습니다. 문제는 프로그래밍보다 수학에 관한 것이지만 여기에 제 아이디어가 있습니다. 나는 페인트했지만 따라갈 :

enter image description here

당신이 사각형을 회전 할 때 newWidth과에 대한 newHeight을 계산해야합니다. 이러한 치수로 새 사각형을 만들고 현재 사각형처럼 왼쪽 위 모서리에 배치하십시오. 알파 α은 회전하려는 각도를 의미합니다. 회전이 끝나면이 새로운 사각형을 오른쪽으로 이동해야합니다 (축척은 X). 그리기 영역에 완벽하게 배치 할 수있는 가장 큰 사각형이 있습니다.

코드에 대한 몇 가지 아이디어가 있습니다. 나는 그것을 테스트하지 않았다 :

private void Form1_Paint(object sender, PaintEventArgs e) 
    { 
     double angle = 20; 

     double width = Convert.ToDouble(e.ClipRectangle.Width), 
       height = Convert.ToDouble(e.ClipRectangle.Height), 
       h = Math.Sqrt((width*width) + (height*height)), 
       y = (width/h); 

     int newHeight = Convert.ToInt32(height*y), 
      newWidth = Convert.ToInt32(width*y), 
      x = Convert.ToInt32((Math.Sin(angle) * height); 

     e.Graphics.RotateTransform(angle); 
     e.Graphics.DrawRectangle(Pens.Black, x, 0, newWidth, newHeight); 
    }