Jacks_Depression

Jacks_3rd Point

Posted: 2009.10.17 23:52

Now that I have them means, I am going to try and explain in further detail the concept in the Vestigial Appendage post.

Imagine that your looking at a wall in front of you. The point on the wall directly in front of you, we'll call the center. Probably something like this.

Now we are going to add objects to this wall.

If you ever see something that looks exactly like that on your wall, your probably not well. In fact, I hope you don't even see want to see an X and Y axis on your wall. The point is, shapes on your wall will never look this perfect. It is quite unnatural. What your going to see actually looks more like this.

We live in a 3D world and pure 2D shapes don't look natural to us. To make it look more real, depth is needed. Still this image is not exactly accurate. The depths have been exaggerated a little too much. This is the equivalent of using a wide angle lens on a camera. Its true that the further away something is on this plane the more of the side you will see. However, this one doesn't quite hit the nail on the head either. The check mark is the only shape I think has proper depth in this image. So if I where to use this method of displaying objects I would have to make every depth as minor as the check mark's.

And that explains why I abandoned the idea. Simply that the little amount of depth that is added will take a lot of calculations and make it look only slightly better. It was not worth slowing the game down in my opinion. I only hope that the person who ends up deigning the units is good at making things appear to have depth.


Now lets dig into how I accomplished this. Here are all the keywords for everything I will be using for this explanation: Flex, Flash, ActionScript, CaRMetal, Transformation Matrix.

When starting on this test, I had two unknowns.

  1. How to transform a bitmap in ActionScript.
  2. How to calculate the visible length of the depth.

First question was answered by research. I ended up finding this library thanks to http://flashandmath.com/ that will do all the transforms I need.

The BitmapTransformer Class

From here, we get to work on the object we will display. I started by caching the location of each corner. If you know your ActionScript, this wont be a hard task for you. For this example, we are going to store our point clockwise starting from the upper left: [(3,4), (4,4), (3,2), (4,2)]

private var corners:Array = new Array(

   
new Point(3,4),

   
new Point(4,4),

   
new Point(3,2),

   
new Point(4,2)

);

This image was generated by CaRMetal. (My new favorite toy)

I had deigned my test to work with any number of points but we will keep it simple with a four sided figure. Each side will also have four points. Two of them will be from our recorded points. The other two will have to be generated from the distance to the center (0,0) and the angle. My solution was to loop through all the points and do each side based on the next point.

drawLayer.graphics.clear();
for(var i:int = 0; i < corners.length; i++)

{
   
var j:Number = i + 1;

   
if(j >= corners.length)

   
{

       
j -= corners.length;

   
}

   

   
var point1:Point = corners[i];

   
var point2:Point = corners[j];

   
var lensSlope:Number = utils.TwoPointSlope(unitPoint, lensFocalPoint);

   
var point3:Point = utils.CalculatePointVector(point2, lensSlope, distance, 1.0);
   
var point4:Point = utils.CalculatePointVector(point1, lensSlope, distance, 1.0);



   
var xMap:BitmapTransformer = new BitmapTransformer(sides[i].width, sides[i].height, settings.transformQuality, settings.transformQuality);

   
xMap.mapBitmapData(sides[i].bitmapData, point1, point2, point3, point4, pintOn);
}

This code is to be run every time the shape moves. Put it in your main loop. First we start with main point for this side of the object. Which will be point "i" (you can also call it side "i"). Then we need the next point on the object which will be point "j" (this is still side "i" though). These are quickly resolved into points 1 and 2. So, now we have two points of the four we need to draw a side.

Next thing the code does is to call a utility function that will give us the slope of a line based on two points. In this case, we want the slope of an imaginary line drawn between the center of the object and the center of the stage. This would also be the location for the imaginary lens we are trying to recreate. Assuming we are currently calculating the 4th side (green). We do not need to think about any other sides (brown). And remember, since we sored our points in a clockwise fashion, we label the bottom left point as point1 (or point "i") and top left as point2 (or point "j").

Now every side point knows which direction the center is in and can be drawn properly. Continuing with the code above; points 3 and 4 are then calculated and the side is drawn. Which would look something like this.

And thats the basic idea. The final part of this problem is to find out the magic that was done to find those last two points. The "CalculatePointVector" function.

public static function CalculatePointVector(origin:Point, radDirection:Number, speed:Number, time:Number):Point

{
   
var result:Point = new Point();

   
result.x = (Math.sin(radDirection) * speed * time) + origin.x;

   
result.y = (Math.cos(radDirection) * speed * time) + origin.y;

   
return result;

}

Now that does not look to complex at all. In this function we have: the point want to base the new point off of, the direction the slope was pointing in radians and some variables to help me control how much depth you see. Speed and time are really distance in this calculation.

Even so, there is a much easier way to calculate all this. Its called a Transformation Matrix. I took it upon my self to re-invent the wheel for my own knowledge. Although ActionScript has its own tools to help you with this.

http://livedocs.adobe.com/flex/3/langref/flash/geom/Matrix.html

Basically you add up from left to right and you get the new position of your point. Sadly, its not very clear how to do that with a single point. I don't know much how they work any way. All I know is that I was looking for a way to rotate a single point and found this did the job. Thus why I shared my code with you! Hope it helped or you learned something.