AlecMcE.com

Coding on the Flash Platform

Archive for the ‘math’ Category

Gotcha – transform.matrix and scaleX/Y

View Comments

I came across this gotcha for the first time today. Praise-be to ASUnit, without which this could have been extremely difficult to unearth:

// given two sprites called "a" and "b"...

a.transform.matrix = new Matrix(-.5, 0, 0, -.5, a.x, a.y);
b.scaleX = b.scaleY = -.5;

trace(a.scaleX, a.scaleY, b.scaleX, b.scaleY); // outputs: 0.5, 0.5, -0.5, -0.5

Both clips have been scaled by -0.5, but because the transform was used to produce the scale for a, the scaleX/Y variables do not reflect the object’s true scale.

Now, just to confuse yourself, add a third sprite to the stage:

// given another sprite called "c"...

c.transform.matrix = new Matrix(-.5, 0, 0, -.5, c.x, c.y);
c.scaleX = c.scaleY = -.5;

Curiouser and curiouser! This needed a more complete experimentation…

The Flash plugin is required to view this object.

The source for this experiment can be found here: scaleAndTransform. The buttons call the following methods:

function onGo(event:Event):void
{
	a.transform.matrix = new Matrix(-.5, 0, 0, -.5, a.x, a.y);

	b.scaleX = b.scaleY = -.5;

	c.transform.matrix = new Matrix(-.5, 0, 0, -.5, c.x, c.y);
	c.scaleX = c.scaleY = -.5;
}

function onResetScale(event:Event):void
{
	a.scaleX = a.scaleY = 1;
	b.scaleX = b.scaleY = 1;
	c.scaleX = c.scaleY = 1;
}

function onResetTransform(event:Event):void
{
	a.transform.matrix = new Matrix(1, 0, 0, 1, a.x, a.y);
	b.transform.matrix = new Matrix(1, 0, 0, 1, b.x, b.y);
	c.transform.matrix = new Matrix(1, 0, 0, 1, c.x, c.y);
}

What Is Going On?

If you apply a transformation matrix then a scale, the magnitude of the scale is applied, but the direction is determined by the product of the transformation and the scalar… which is to say that:

a.realScaleX = (a.transform.matrix.a * a.scaleX > 0 ? 1 : -1) * a.scaleX;

If however you apply a scale then a transformation, the scale is defined by the transformation only!

a.realScaleX = a.transform.matrix.a;

Bug?

Does this qualify as a bug? I haven’t thought about this for long enough. The conditions in which a transformation matrix rotates and skews the MovieClip confuse me; how would I define scaleX and scaleY in that scenario? I need to give this some thought; perhaps you the community can give me some help! I am reluctant to call anything a bug immediately now, after my experience with my The Problem With Vector.<T> post, where I was just plain wrong!

A similar bug exists in Adobe JIRA: UIComponent.scaleX, scaleY differ from transform.matrix.a,d. You’ll need an account to look at this – it’s free, and once you’ve got it you can pester Adobe with your bugs too.

Written by alec

February 23rd, 2010 at 9:00 am

Posted in as3, gotcha, math, tdd

Circle Segments

View Comments

I’ve added circle segments to the as3geometry library. The two examples below demonstrate the definition of a segment by two vertices constrained to the circle radius and by a line and circle:

Circle Segment By Vertices

The Flash plugin is required to view this object.


view source | click-and-drag the red points to interact

Circle Segment By Line And Circle

The Flash plugin is required to view this object.


view source | click-and-drag the red points to interact

The library update also includes some preliminary work on the intersection of two polygons, but I haven’t yet sorted out the mutability yet, because it’s pretty complicated, and because I’m furiously busy this December preparing to move from the UK to the USA! Expect more udpates from late January onwards, once I’m settled in.

Written by alec

December 21st, 2009 at 1:01 pm

Posted in as3, library, math

as3geometry – line & circle intersection

View Comments

Addition to my as3geometry library, the intersection between a line and a circle

The Flash plugin is required to view this object.


view source | click-and-drag the red points to interact

Written by alec

December 2nd, 2009 at 9:32 pm

Posted in as3, library, math

as3geometry – line & line intersection

View Comments

Addition to my as3geometry library, the Intersection between two lines (though in this case the lines are a ray and a segment!)

The Flash plugin is required to view this object.


view source | click-and-drag the red points to interact

Written by alec

December 2nd, 2009 at 9:32 pm

Posted in as3, library, math

Tagged with

as3geometry Update

View Comments

I’ve been working on a GitHub geometry library recently.

The Flash plugin is required to view this object.


view source | click-and-drag the red points to interact

I’ve created various of these over the years, AS1, AS2, AS3, and now AS3+as3signals. It is gratifying to finally have the means to define events in interfaces!

The work uses the alpha of ASUnit version 4 (Rob Penner’s ‘Free Runner’ implementation, though it is not purely Test-Driven Development because in some cases I am refactoring old hitherto-private code. However, the classes in the test repository might serve as a useful example of the upcoming ASUnit library.

The work aims for elegance of structure rather than speed, and I will be concentrating on the Euclidean 2D for the time-being, though may look at extending it into 3D or non-Euclidean plane structures if I ever have the time.

http://github.com/alecmce/as3geometry

Next Steps

  • Circle-Line intersections
  • Polygon-Polygon intersections (Vertices)
  • Polygon-Polygon intersections (Polygons)
  • Circle-Circle intersection (Vertices)
  • Circle-Line intersection
  • Circle Sectors
  • Circle Rays
  • Circle-Circle intersection (Lens)
  • Circle-Circle intersection
  • Bezier Curves
  • Parabola

Written by alec

November 25th, 2009 at 11:03 pm

Posted in as3, library, math

Tagged with

Vector – Annoying Naming Conventions

View Comments

When Adobe released the Flash Player 10 last year, it facilitated a new class, a strongly-typed array: Vector.<T>. I suppose we should all be grateful; now we can finally type arrays, leading to more robust code. I don’t feel very grateful, though. Adobe has given me a headache.

In Geometry the word “vector” has a clear meaning: a vector describes a translation in space. To differentiate from other uses of the word, Wikipedia offer the terms Euclidean, Spatial or Geometric Vector. We recognise this use of the word because every single Flash coder understands the distinction between vector graphics and raster (or bitmap) graphics.

I have been working on a Geometric library recently (my as3voronoi library), and have found the need to create an interface to encapsulate a translation in Cartesian space. What will I call it? It’s a vector, but “Vector” is going to cause a lot of headaches, because Adobe’s new Vector class is in the default namespace.

Which leads me to an utterly futile question: why on earth would they call their strongly-typed array class “Vector”? Why not facilitate the strong-typing of Arrays, since Array is the existing term? Untyped Arrays could be considered functionally equivalent to Array.<*> or Array.<Object>. I realise that Adobe cannot change this decision now it has been made, but why did they do it in the first place?

The only answer that I can see is that the vector class is in the C++ standard template library as a one-dimensional array. Was the decision made on the basis that if it’s good enough for C++, then it’s good enough for Flash? I hope not, because the Array class is not like the C++ array, and I don’t see “bitset”, “deque”, “list”, “map”, “queue”, “set”, or “stack” anywhere in the Flash library. Why adopt the C++ convention in just this context?

Flash has a different context to C++. Flash is a word used to describe a player that uses ActionScript and a vector drawing tool rolled into one. Surely the word “vector” has particular significance for the users of Adobe technology?

So what do I call my vector interface? “Vector2D”? “EuclideanVector”? I haven’t called my Polygon interface “Polygon2D” or “EuclideanPolygon”, nor my line interface “Line2D” or “EuclideanLine”. I don’t need to. The terse name does the job perfectly well. If I only target Flash Player 9 I don’t need to call my vector interface anything other than “Vector”.

The headache is unresolved; I am stuck with wanting an array to be an Array and a vector to be a Vector, but will have to accept that an array will be a Vector and a vector … something else.

Written by alec

August 31st, 2009 at 3:39 pm

Permutations in AS3

View Comments

I needed a method to find permutations of elements within an Array, for a little something that I’m working on. I couldn’t find one ‘off the shelf’, and while it’s easy enough to do yourself, it’s easier to use someone else’s. If you’re not very familiar with the concept of permutations, please be sure to read the method header if you intend to use this method.

/**
 * Finds the permutations of an array by recursively permutating sub-arrays
 *
 * WARNING! For n elements there are n! permutations - ie. if you have
 * 6 elements in your array you will find returned an array containing
 * 6*5*4*3*2 = 720 arrays of your elements. 10 elements returns an
 * array containing more than 3.5 million arrays, which is not
 * recommended.
 *
 * @param elements The elements to be permutated
 * @return An array of all of the permutations of the elements in the array.
 */
public function permutate(elements:Array):Array
{
	if (elements.length == 1)
		return [elements[0]];

	var permutations:Array = [];
	var length:int = elements.length;

	var i:int, j:int;
	var tmp:Array;
	var sub:Array;

	i = length;
	while (i--)
	{
		tmp = elements.slice(0, i).concat(elements.slice(i + 1, length));
		sub = permutate(tmp);

		j = sub.length;
		while (j--)
		{
			tmp = [elements[i]].concat(sub[j]);
			permutations.push(tmp);
		}
	}

	return permutations;
}

Written by alec

August 17th, 2009 at 12:05 pm

Posted in as3, math