Friday, 15 January 2010

c# - Calculate the maximum available area after TranslateTransform -



c# - Calculate the maximum available area after TranslateTransform -

let's want draw rectangle angle within windows form.

i can with

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); }

but rotate rectangle , left , bottom part missing.

but want achive want draw biggest possible rectangle angle within form this

what's best way this?

we can find rectangle @ angle θ touches 4 sides. if allow w, h width , height of our window, th angle in radians known beforehand. allow a, b width , height of rectangle trying fit in box, these 2 values wish find. allow x0,y0 coordinates of point in center of window x0=w/2, y0=h/2. 1 of corners of rectangle be

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

the other point similar different signs. bit of trigonometry show this.

for rectangle touch sides want

a * sin(th) + b cos(th) = w * cos(th) + b sin(th) = h

this gives pair of simultaneous equations can solve. multiply first sin(th) , sec cos(th)

a * sin(th) sin(th) + b cos(th) sin(th) = w sin(th) * cos(th) cos(th) + b sin(th) cos(th) = h cos(th)

subtract

a ( sin(th) sin(th) - cos(th) cos(th) ) = w sin(th) - h cos(th)

divide ( sin(th) sin(th) - cos(th) cos(th) ) gives

a = (w sin(th) - h cos(th)) / ( sin(th) sin(th) - cos(th) cos(th) )

a similar process gives

b = (h sin(th) - w cos(th)) / ( sin(th) sin(th) - cos(th) cos(th) )

once have , b can calculate corners of rectangles , draw it.

i've set code in jsfiddle http://jsfiddle.net/salixalba/5jct7/ code is

// canvas , 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 vars b/ they're used var w = canvas.width; var h = canvas.height; var spinner = $( "#startang" ).spinner({ spin: function( event, ui ) { if ( ui.value > 180 ) { $( ).spinner( "value", ui.value - 360 ); draw(); homecoming false; } else if ( ui.value < -180 ) { $( ).spinner( "value", ui.value + 360 ); draw(); homecoming 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 = (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 * * math.sin(th) + 0.5 * b * math.cos(th); var y1 = y0 + 0.5 * * math.cos(th) + 0.5 * b * math.sin(th); var x2 = x0 - 0.5 * * math.sin(th) - 0.5 * b * math.cos(th); var y2 = y0 + 0.5 * * math.cos(th) - 0.5 * b * math.sin(th); var x3 = x0 + 0.5 * * math.sin(th) + 0.5 * b * math.cos(th); var y3 = y0 - 0.5 * * math.cos(th) + 0.5 * b * math.sin(th); var x4 = x0 + 0.5 * * math.sin(th) - 0.5 * b * math.cos(th); var y4 = y0 - 0.5 * * 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();

note not give largest rectangle there may larger 1 touch 2 sides, there limit on possible angle.

c# .net winforms drawing rectangles

No comments:

Post a Comment