Calculating an overlay of day/night for Google Maps - google-maps

I am trying to find a way to create an overlay for Google Maps API V3 that shows the sunlit areas of the world. This is the basic result I am looking for:
http://www.daylightmap.com/index.php
But want more control over the appearance (ideally just a 10% black overlay with no city lights). I can draw the shape in a canvas element but can not figure out how to calculate the shape based on earth's tilt and rotation etc.
Any help would be appreciated.
EDIT: Javascript
I still don't know where to implement the y-offset variable below. I also need to figure out how to adjust/stretch the y-offset from this (equal distant latitudinal lines) to mercator (closer at poles).
// Get the canvas element
var ctx = document.getElementById('canvas').getContext('2d');
ctx.clearRect( 0, 0, 800, 620 );
// Current time
var map_width = $("#canvas").width();
var map_height = $("#canvas").height();
var now = new Date();
var cur_hour = now.getHours();
var cur_min = now.getMinutes();
var cur_sec = now.getSeconds();
var cur_jul = now.julianDate() - 1;
var equinox_jul = new Date(now.getFullYear(),2,20,24,-now.getTimezoneOffset(),0,0).julianDate() - 1;
var offset_x = Math.round(((cur_hour*3600 + cur_min*60 + cur_sec)/86400) * map_width); // Resulting offset X
var offset_sin = ((365.25 - equinox_jul + cur_jul)%365.25)/365.25; // Day offset, mapped on the equinox offset
var offset_sin_factor = Math.sin(offset_sin * 2 * Math.PI); // Sine wave offset
var offset_y = offset_sin_factor * 23.44; // Map onto angle. Maximum angle is 23.44° in both directions
var degrees_per_radian = 180.0 / Math.PI;
var offset_y_mercator = Math.atan( offset_y.sinh() ) * degrees_per_radian;
// Global wave variables
var period = 1 / 6.28291; // Original value 2Pi: 6.28291
var amplitude = (map_height/2);
// Draw vertical lines: One for each horizontal pixel on the map
for( var x = 0; x <= map_width; x++ ) {
ctx.beginPath();
// Start at the bottom of the map
ctx.moveTo(x,map_height);
// Get the y value for the x pixel on the sine wave
var y = (map_height/2) - (Math.sin( (offset_x / map_width) / period ) * amplitude);
offset_x++;
// Draw the line up to the point on the sine wave
ctx.lineTo(x,y);
ctx.stroke();
}

If you want it to be physically accurate, you actually need to consider two offsets: a vertical (depending on the current date) and a horizontal (depending on the current time).
The horizontal offset X may be calculated by looking at the current time on some fixed geographic location on earth. The shadow offset will be 0 at midnight and will increase by 1/86400 for each seconds after midnight. So the formular is
offsetX = (curHour*3600 + curMinute*60 + curSeconds)/86400
The vertical offset will change between the Solstices on June 21st and Dec 22nd (if it's not a leap year, where the Solstices are on June 20th and Dec 21st). The maximum angles are 23.44° in both directions. We have 90° per hemisphere and 365/2 = 182.5 days between the two solstices, and we are working with a mapping of a circular motion, so a sin()-function has to be used. The wavelength of a sinus wave is 2pi, so we need pi for half the vertical offset Y of one year.
Please note, that I did not take leap seconds into account, so the calculation might be a bit off in the distant past/future.
// current time
$curHour = date("H");
$curMin = date("i");
$curSec = date("s");
// resulting offset X
$offsetX = ($curHour*3600 + $curMin*60 + $curSec)/86400;
echo "======== OFFSET X ==========\n";
echo "curHour: $curHour\n";
echo "curMin: $curMin\n";
echo "curSec: $curSec\n";
echo "offsetX: $offsetX\n\n";
// spring equinox date as day of year
$equinox = date("z", mktime(0, 0, 0, 3, 20));
// current day of year
// first line is for testing purposes
//$curDay = date("z", mktime(0, 0, 0, 6, 21));
$curDay = date("z");
// Day offset, mapped on the equinox offset
$offsetSin = ((365.25 - $equinox + $curDay)%365.25)/365.25;
// sinus wave offset
$offsetSinFactor = sin($offsetSin * 2 * pi());
// map onto angle
$offsetY = $offsetSinFactor * 23.44;
// optional: Mercator projection
$degreesPerRadian = 180.0 / pi();
$offsetYmercator = atan(sinh($offsetY)) * $degreesPerRadian;
// missing: mapping onto canvas height (it's currently
// mapped on $offsetY = 90 as the total height of the
// canvas.
echo "========= OFFSET Y =========\n";
echo "equinox day: $equinox\n";
echo "curDay: $curDay\n";
echo "offsetSin: $offsetSin\n";
echo "offsetSinFac: $offsetSinFactor\n";
echo "offsetY: $offsetY\n";
echo "offsetYmerc: $offsetYmercator\n";
You should be able to port this calculation to any language you want.

You asked for more control over appearance
Check out the Geocommons JS api, which may be more suited to your purpose than Google Maps.
If you're going for flexibility, GEOS would be preferable to drawing the shape for a specific projection. I know there are php bindings, but I haven't used them myself.
Helmer Aslaksen has a great writeup about heavenly mathematics that should help you create an alorithm to draw a sunlit-area polygon using geos. You can test your code against measured sunrise/sunset times for accuracy.
Edit 1
Must be Python and Google Maps, you say?
You can overlay data with KML,
which will allow you to set a background color as you request.
I like using the interactive sampler to get a feel for how things will look.
Check out the Shapely package on pypi,
and a discussion on how to create kml from it.

Related

Could someone explain me w.r.t. coordinates

Could someone please explain me what are w.r.t. coordinates? or at least direct me to a place that explains what they are? I've being searching for two days or so and all that I found is tutorials on how are they used but not what they actually are or even what wrt stand for.
These tutorials take the assumption I already know what they are which is stressful because I've never heard of them.
I'm working in as3 trying to do some parametric surfaces using pixel particles and I understand these are kind of useful while moving the particles around.
This is the relevant function where they are used as u,v and w, where p is a single particle that also contains xyz values that are not being modified.
function onEnter(evt:Event):void {
dphi = 0.015*Math.cos(getTimer()*0.000132);
dtheta = 0.017*Math.cos(getTimer()*0.000244);
phi = (phi + dphi) % pi2;
theta = (theta + dtheta) % pi2;
cost = Math.cos(theta);
sint = Math.sin(theta);
cosp = Math.cos(phi);
sinp = Math.sin(phi);
//We calculate some of the rotation matrix entries here for increased efficiency:
M11 = cost*sinp;
M12 = sint*sinp;
M31 = -cost*cosp;
M32 = -sint*cosp;
p = firstParticle;
//////// redrawing ////////
displayBitmapData.lock();
//apply filters pre-update
displayBitmapData.colorTransform(displayBitmapData.rect,darken);
displayBitmapData.applyFilter(displayBitmapData, displayBitmapData.rect, origin, blur);
p = firstParticle;
do {
//Calculate rotated coordinates
p.u = M11*p.x + M12*p.y + cosp*p.z;
p.v = -sint*p.x + cost*p.y;
p.w = M31*p.x + M32*p.y + sinp*p.z;
//Calculate viewplane projection coordinates
m = fLen/(fLen - p.u);
p.projX = p.v*m + projCenterX;
p.projY = p.w*m + projCenterY;
if ((p.projX > displayWidth)||(p.projX<0)||(p.projY<0)||(p.projY>displayHeight)||(p.u>uMax)) {
p.onScreen = false;
}
else {
p.onScreen = true;
}
if (p.onScreen) {
//we read the color in the position where we will place another particle:
readColor = displayBitmapData.getPixel(p.projX, p.projY);
//we take the blue value of this color to represent the current brightness in this position,
//then we increase this brightness by levelInc.
level = (readColor & 0xFF)+levelInc;
//we make sure that 'level' stays smaller than 255:
level = (level > 255) ? 255 : level;
/*
We create light blue pixels quickly with a trick:
the red component will be zero, the blue component will be 'level', and
the green component will be 50% of the blue value. We divide 'level' in
half using a fast technique: a bit-shift operation of shifting down by one bit
accomplishes the same thing as dividing by two (for an integer output).
*/
//dColor = ((level>>1) << 8) | level;
dColor = (level << 16) | (level << 8) | level;
displayBitmapData.setPixel(p.projX, p.projY, dColor);
}
p = p.next;
} while (p != null)
displayBitmapData.unlock();
}
This is the example I'm using http://www.flashandmath.com/flashcs4/light/
I kinda understand how are they used but I don't get why.
Thanks in advance.
PD: kind of surprised there is not even a tag related to it.
In that Particle3D.as class linked, they have:
//coords WRT viewpoint axes
public var u:Number;
public var v:Number;
public var w:Number;
From the code example you posted to the question it becomes clear that coords WRT viewpoint axes means coordinates with respect to viewpoint axes, since the code is doing exactly that .
What they are doing is a Camera (or Viewing) Transformation, where the Particle's world coordinates (x,y,z) is transformed from the world coordinate system to coordinates in the camera (or view) coordinate system (u,v,w).
(x,y,z) are the coordinates of the particle in the world coordinate system
(u,v,w) are the coordinates of the particle in the camera coordinate system
For example, the world coordinate system might have an origin at (0,0,0) with the camera positioned at something like (5,3,6) with an lookat vector of (1,0,0) and up vector of (0,1,0).

AS3 drawing lines, making shorter after that

i have a little math/coding problem witch i don`t have any idea how could i do it work in a simple way, so the problem is is need to make a line shorter, with 15
in my program i have :
http://gyazo.com/aff5ff61fb9ad3ecedde3118d9c0895e
the line takes the center coordinates of both circles and draws from one to another, but i need it to be from the circumference of the circles, so it wont get inside
the code im using is :
var line:Shape = new Shape();
line.graphics.lineStyle(3,0xFF0000,2);
line.graphics.moveTo(sx,sy);
line.graphics.lineTo(fx,fy);
this.addChild(line);
arrow2(sx,sy,fx,fy);
var rline:Shape = new Shape();
rline.graphics.lineStyle(3,0xFF0000,2);
rline.graphics.moveTo(fx,fy);
rline.graphics.lineTo(xa,ya);
this.addChild(rline);
var rline2:Shape = new Shape();
rline2.graphics.lineStyle(3,0xFF0000,2);
rline2.graphics.moveTo(fx,fy);
rline2.graphics.lineTo(xb,yb);
this.addChild(rline2);
the rline and rline2 function is for the arrow lines, now my question is how do i make it shorter not depending on it direction so it will not overlap the circle
You can use vectors to solve your problem; they're pretty easy to get the hang of, and pretty much indispensable for things like game dev or what you're trying to do. You can get an overview here: http://www.mathsisfun.com/algebra/vectors.html or by searching "vector math" in google
So first step is to get a vector from one circle to another (pretty much what you've done):
var vector:Point = new Point( circle2.x - circle1.x, circle2.y - circle1.y );
var length:Number = vector.length; // store the length of the vector for later
This is the equivalent of saying "if you start at circle1 and move along vector, you'll arrive at circle2"
Next thing we're going to do is normalise it; all this does is set the length to 1 - the direction is unchanged - this makes it easier to work with for what you're looking to do. A vector with length 1.0 is called a unit vector:
vector.normalize( 1.0 ); // you can pass any length you like, but for this example, we'll stick with 1.0
Now, to draw a line from one circle to another, but starting from the outside, we simply find the start and the end points. The starting point is simple the position of circle1 plus vector (normalised to unit length) multiplied by the radius of circle1:
var sx:Number = circle1.x + vector.x * circle1.radius; // or circle1.width * 0.5 if you don't store the radius
var sy:Number = circle1.y + vector.y * circle1.radius;
The ending point can be found by starting at our start point, and continuing along our vector for a distance equal to the distance between the two circles (minus their radii). The length value that we created earlier is the distance between your two circles, from one center point to another, so we can use that to get the distance minus the radii:
var dist:Number = length - ( circle1.radius + circle2.radius ); // or circle1.width * 0.5 etc
And so the end point:
var ex:Number = sx + vector.x * dist;
var ey:Number = sy + vector.y * dist;
And to draw the line between them:
var line:Shape = new Shape;
line.graphics.lineStyle( 1.0, 0x000000 );
line.graphics.moveTo( sx, sy );
line.graphics.lineTo( ex, ey );
this.addChild( line )

Mimick photoshop/painter smooth draw on HTML5 canvas?

As many people knew, HTML5 Canvas lineTo() is going to give you a very jaggy line at each corner. At this point, a more preferable solution would be to implement quadraticCurveTo(), which is a very great way to generate smooth drawing. However, I desire to create a smooth, yet accurate, draw on canvas HTML5. Quadratic curve approach works well in smoothing out the draw, but it does not go through all the sample points. In other word, when I try to draw a quick curve using quadratic curve, sometime the curve appears to be "corrected" by the application. Instead of following my drawing path, some of the segment is curved out of its original path to follow a quadratic curve.
My application is intended for a professional drawing on HTML5 canvas, so it is very crucial for the drawing to be both smooth and precise. I am not sure if I am asking for the impossible by trying to put HTML5 canvas on the same level as photoshop or any other painter applications (SAI, painterX, etc.)
Thanks
What you want is a Cardinal spline as cardinal splines goes through the actual points you draw.
Note: to get a professional result you will also need to implement moving average for short thresholds while using cardinal splines for larger thresholds and using knee values to break the lines at sharp corner so you don't smooth the entire line. I won't be addressing the moving average or knee here (nor taper) as these are outside the scope, but show a way to use cardinal spline.
A side note as well - the effect that the app seem to modify the line is in-avoidable as the smoothing happens post. There exists algorithms that smooth while you draw but they do not preserve knee values and the lines seem to "wobble" while you draw. It's a matter of preference I guess.
Here is an fiddle to demonstrate the following:
ONLINE DEMO
First some prerequisites (I am using my easyCanvas library to setup the environment in the demo as it saves me a lot of work, but this is not a requirement for this solution to work):
I recommend you to draw the new stroke to a separate canvas that is on top of the main one.
When stroke is finished (mouse up) pass it through the smoother and store it in the stroke stack.
Then draw the smoothed line to the main.
When you have the points in an array order by X / Y (ie [x1, y1, x2, y2, ... xn, yn]) then you can use this function to smooth it:
The tension value (ts, default 0.5) is what smooths the curve. The higher number the more round the curve becomes. You can go outside the normal interval [0, 1] to make curls.
The segment (nos, or number-of-segments) is the resolution between each point. In most cases you will probably not need higher than 9-10. But on slower computers or where you draw fast higher values is needed.
The function (optimized):
/// cardinal spline by Ken Fyrstenberg, CC-attribute
function smoothCurve(pts, ts, nos) {
// use input value if provided, or use a default value
ts = (typeof ts === 'undefined') ? 0.5 : ts;
nos = (typeof nos === 'undefined') ? 16 : nos;
var _pts = [], res = [], // clone array
x, y, // our x,y coords
t1x, t2x, t1y, t2y, // tension vectors
c1, c2, c3, c4, // cardinal points
st, st2, st3, st23, st32, // steps
t, i, r = 0,
len = pts.length,
pt1, pt2, pt3, pt4;
_pts.push(pts[0]); //copy 1. point and insert at beginning
_pts.push(pts[1]);
_pts = _pts.concat(pts);
_pts.push(pts[len - 2]); //copy last point and append
_pts.push(pts[len - 1]);
for (i = 2; i < len; i+=2) {
pt1 = _pts[i];
pt2 = _pts[i+1];
pt3 = _pts[i+2];
pt4 = _pts[i+3];
t1x = (pt3 - _pts[i-2]) * ts;
t2x = (_pts[i+4] - pt1) * ts;
t1y = (pt4 - _pts[i-1]) * ts;
t2y = (_pts[i+5] - pt2) * ts;
for (t = 0; t <= nos; t++) {
// pre-calc steps
st = t / nos;
st2 = st * st;
st3 = st2 * st;
st23 = st3 * 2;
st32 = st2 * 3;
// calc cardinals
c1 = st23 - st32 + 1;
c2 = st32 - st23;
c3 = st3 - 2 * st2 + st;
c4 = st3 - st2;
res.push(c1 * pt1 + c2 * pt3 + c3 * t1x + c4 * t2x);
res.push(c1 * pt2 + c2 * pt4 + c3 * t1y + c4 * t2y);
} //for t
} //for i
return res;
}
Then simply call it from the mouseup event after the points has been stored:
stroke = smoothCurve(stroke, 0.5, 16);
strokes.push(stroke);
Short comments on knee values:
A knee value in this context is where the angle between points (as part of a line segment) in the line is greater than a certain threshold (typically between 45 - 60 degrees). When a knee occur the lines is broken into a new line so that only the line consisting of points with a lesser angle than threshold between them are used (you see the small curls in the demo as a result of not using knees).
Short comment on moving average:
Moving average is typically used for statistical purposes, but is very useful for drawing applications as well. When you have a cluster of many points with a short distance between them splines doesn't work very well. So here you can use MA to smooth the points.
There is also point reduction algorithms that can be used such as the Ramer/Douglas/Peucker one, but it has more use for storage purposes to reduce amount of data.

How to create intensity mask for heatmap?

I'm trying to develop heat map, now initially I would have to draw the intensity mask, and since I'm using GWT so I have randomly generated some coordinates and placed my circles ( with required gradience ) at those locations so the output comes out to be circles overlapping each other. And If I look at the intensity mask from Dylan Vester, it comes to be very smooth How can I draw my heat map ?? Also how the output is achieved similar to Dylan Vester?? Question also is if I'm drawing circles then how to decide the intensity at the intersection of two or more circles, how they have achieved ?? Here is my code
// creating the object for the heat points
Heat_Point x = new Heat_Point();
// Variables for random locations
int Min = 1,Max = 300;
int randomx,randomy;
// Generating set of random values
for( int i = 0 ; i < 100 ; i++ ) {
// Generating random x and y coordinates
randomx = Min + (int)(Math.random() * ((Max - Min) + 1));
randomy = Min + (int)(Math.random() * ((Max - Min) + 1));
// Drawing the heat points at generated locations
x.Draw_Heatpoint(c1, randomx, randomy);
}
And Here is how I'm plotting my heat point that is Heat_Point class
Context con1 = c1.getContext2d(); // c1 is my canvas
CanvasGradient x1;
x1 = ((Context2d) con1).createRadialGradient(x,y,10,x,y,20);
x1.addColorStop(0,"black");
x1.addColorStop(1,"white");
((Context2d) con1).beginPath();
((Context2d) con1).setFillStyle(x1);
((Context2d) con1).arc(x,y,20, 0, Math.PI * 2.0, true);
((Context2d) con1).fill();
((Context2d) con1).closePath();`
here I was supposed to add some images but I didn't have enough reputation :D :P
I took a quick look at HeatmapJS (http://www.patrick-wied.at/static/heatmapjs/) and it seems he uses radial gradients (like you have above) and he also uses opacity and a color filter called "multiply blend" to smooth out the intensity of the colors in the heat map.
His code is quite impressive. It's open source, so you might want to check it out!

How to get unrotated display object width/height of a rotated display object?

If I create a rectangle with 100px width and 100px height and then rotate it, the size of the element's "box" will have increased.
With 45 rotation, the size becomes about 143x143 (from 100x100).
Doing sometimes like cos(angleRad) * currentWidth seems to work for 45 rotation, but for other bigger angles it doesn't.
At the moment I am doing this:
var currentRotation = object.rotation;
object.rotation = 0;
var normalizedWidth = object.width;
var normalizedHeight = object.height;
object.rotation = currentRotation;
Surely, there must be a better and more efficient way. How should I get the "normalized" width and height of a displayobject, aka the size when it has not been rotated?
The best approach would probably be to use the code posted in the question - i.e. to unrotate the object, check its width, and then re-rotate it. Here's why.
First, simplicity. It's obvious what's being done, and why it works. Anyone coming along later should have no trouble understanding it.
Second, accuracy. Out of curiosity I coded up all three suggestions currently in this thread, and I was not really surprised to find that for an arbitrarily scaled object, they give three slightly different answers. The reason for this, in a nutshell, is that Flash's rendering internals are heavily optimized, and among other things, width and height are not stored internally as floats. They're stored as "twips" (twentieths of a pixel) on the ground that further accuracy is visually irrelevant.
Anyway, if the three methods give different answers, which is the most accurate? For my money, the most correct answer is what Flash thinks the width of the object is when it's unrotated, which is what the simple method gives us. Also, this method is the only one that always give answers rounded to the nearest 1/20, which I surmise (though I'm guessing) to mean it's probably equal to the value being stored internally, as opposed to being a calculated value.
Finally, speed. I assume this will surprise you, but when I coded the three methods up, the simple approach was the fastest by a small margin. (Don't read too much into that - they were all very close, and if you tweak my code, a different method might edge into the lead. The point is they're very comparable.)
You probably expected the simple method to be slower on the grounds that changing an object's rotation would cause lots of other things to be recalculated, incurring overhead. But all that really happens immediately when you change the rotation is that the object's transform matrix gets some new values. Flash doesn't really do much with that matrix until it's next time to draw the object on the screen. As for what math occurs when you then read the object's width/height, it's difficult to say. But it's worth noting that whatever math takes place in the simple method is done by the Player's heavily optimized internals, rather than being done in AS3 like the algebraic method.
Anyway I invite you to try out the sample code, and I think you'll find that the simple straightforward method is, at the least, no slower than any other. That plus simplicity makes it the one I'd go with.
Here's the code I used:
// init
var clip:MovieClip = new MovieClip();
clip.graphics.lineStyle( 10 );
clip.graphics.moveTo( 12.345, 37.123 ); // arbitrary
clip.graphics.lineTo( 45.678, 29.456 ); // arbitrary
clip.scaleX = .87; // arbitrary
clip.scaleY = 1.12; // arbitrary
clip.rotation = 47.123; // arbitrary
// run the test
var iterations:int = 1000000;
test( method1, iterations );
test( method2, iterations );
test( method3, iterations );
function test( fcn:Function, iter:int ) {
var t0:uint = getTimer();
for (var i:int=0; i<iter; i++) {
fcn( clip, i==0 );
}
trace(["Elapsed time", getTimer()-t0]);
}
// the "simple" method
function method1( m:MovieClip, traceSize:Boolean ) {
var rot:Number = m.rotation;
m.rotation = 0;
var w:Number = m.width;
var h:Number = m.height;
m.rotation = rot;
if (traceSize) { trace([ "method 1", w, h ]); }
}
// the "algebraic" method
function method2( m:MovieClip, traceSize:Boolean ) {
var r:Number = m.rotation * Math.PI/180;
var c:Number = Math.abs( Math.cos( r ) );
var s:Number = Math.abs( Math.sin( r ) );
var denominator:Number = (c*c - s*s); // an optimization
var w:Number = (m.width * c - m.height * s) / denominator;
var h:Number = (m.height * c - m.width * s) / denominator;
if (traceSize) { trace([ "method 2", w, h ]); }
}
// the "getBounds" method
function method3( m:MovieClip, traceSize:Boolean ) {
var r:Rectangle = m.getBounds(m);
var w:Number = r.width*m.scaleX;
var h:Number = r.height*m.scaleY;
if (traceSize) { trace([ "method 3", w, h ]); }
}
And my output:
method 1,37.7,19.75
Elapsed time,1416
method 2,37.74191378925391,19.608455916982187
Elapsed time,1703
method 3,37.7145,19.768000000000004
Elapsed time,1589
Surprising, eh? But there's an important lesson here about Flash development. I hereby christen Fen's Law of Flash Laziness:
Whenever possible, avoid tricky math by getting the renderer to do it for you.
It not only gets you done quicker, in my experience it usually results in a performance win anyway. Happy optimizing!
Here's the algorithmic approach, and its derivation.
First, let's do the opposite problem: Given a rectangle of unrotated width w, unrotated height h, and rotation r, what is the rotated width and height?
wr = abs(sin(r)) * h + abs(cos(r)) * w
hr = abs(sin(r)) * w + abs(cos(r)) * h
Now, try the problem as given: Given a rectangle of rotated width wr, rotated height hr, and rotation r, what is the unrotated width and height?
We need to solve the above equations for h and w. Let c represent abs(cos(r)) and s represent abs(sin(r)). If my rusty algebra skills still work, then the above equations can be solved with:
w = (wr * c - hr * s) / (c2 - s2)
h = (hr * c - wr * s) / (c2 - s2)
You should get the bounds of your square in your object's coordinate space (which means no rotations).
e.g.
var b:Sprite = new Sprite();
b.graphics.lineStyle(0.1);
b.graphics.drawRect(0,0,100,100);
b.rotation = 10;
trace('global coordinate bounds: ' + b.getBounds(this));//prints global coordinate bounds: (x=-17.35, y=0, w=115.85, h=115.85);
trace('local coordinate bounds: ' + b.getBounds(b));//prints local coordinate bounds: (x=0, y=0, w=100, h=100)
HTH,
George
Chip's answer in code:
// convert degrees to radians
var r:Number = this.rotation * Math.PI/180;
// cos, c in the equation
var c:Number = Math.abs(Math.cos(r));
// sin, s in the equation
var s:Number = Math.abs(Math.sin(r));
// get the unrotated width
var w:Number = (this.width * c - this.height * s) / (Math.pow(c, 2) - Math.pow(s, 2));