Equally distribute objects across a bezier curve - actionscript-3

Can somebody walk me through how this madness works:
http://www.youtube.com/watch?v=KL8QLLmUvbg
Specifically I'm interested in equally distributing a given number of squares along a path. I'm also wondering if this would work with multiple line segments-- this is one curved segment and I need a solution to distribute objects across one big line with multiple curves in it.
Basically I'm trying to make a tail that realistically follows a character.
Thanks

First a Bezier spline is a curve parametrized by t. However t is not arc-length along the curve. So the procedure is this.
Calculate the length of the bezier curve.
Find the t values that divide the curve into N equal length segments.
However these two steps are tricky.
The first has a closed form solution only for quadratic Beziers. (You can find the solution here )
Otherwise you use a subdivide and approximate approach, or a numerical integration approach (and in some sense these are equivalent - I'd go the numerical integration approach as this has better provable behavior at the cost of slightly trickier implementation, but you may or may not care about that.)
The second is basically a guess a t value, and improve approach (using the same style of calculation at each step as step 1). I'd implement this using a secant style search, as I suspect the derivatives required to use a Newton's method search would be too expensive to calculate.
Once you've got the positions of the objects, you need to use the curve tangent and cotangent to create a local reference frame for the object. This allows the objects to sit nicely in the path of the curve, rather than all having the same orientation. Note that this only works nicely in 2D - in 3D you can still get some weird behavior with object orientation.

You can start by looking into how a bezier curve is calculated. Wikipedia has some nice animations with the explanation and this link has some as3 code.
but if you're trying to create a tail, there are simpler ways of doing that, like using following behaviour or a physics library

I ended up creating a following behavior system like Daniel recommended for simplicities sake. But to elaborate on Michael's awesome answer I stumbled onto this tutorial which details the the spline technique.
http://gamedev.tutsplus.com/tutorials/implementation/create-a-glowing-flowing-lava-river-using-bezier-curves-and-shaders/

Related

AS3: How to intersect vectors at runtime?

Let's say I use the Graphics class at runtime to draw some vector shapes dynamically. For example a square and a circle.
Is there a way to create a new shape at runtime where those 2 vectors shapes overlap?
Those kind of operations are very common in all vector design programs such as Illustrator, Corel, etc... but I haven't found anything in Adobe's documentation, nor anywhere else, to do it by code.
Although drawing operations on the Graphics class are described in terms of lines, points etc this is - as far as you're concerned - just telling it what to draw onto a bitmap. There's no way to remove a shape once drawn, short of clear(), which just wipes the whole thing clean.
I don't fully understand why, as the vector data must be retained - there's no loss of quality on scaling after drawing, for example.
If you don't want to get into some hardcore maths (for anything beyond straight lines, you'll need to) there's an answer here which might help if you've ever used PixelBender:
How to calculate intersection between shapes in flash / action script ? (access to shape's segments and nodes?)
Failing that, if it's just cosmetic you could play around with masking shapes (will probably end up quite hacky though) - however, if you actually want to use the intersection to draw or describe a shape you will need to dig out your maths book or look for a good graphics library.
Hope this helps

Vector graphics flood fill algorithms?

I am working on a simple drawing application, and i need an algorithm to make flood fills.
The user workflow will look like this (similar to Flash CS, just more simpler):
the user draws straight lines on the workspace. These are treated as vectors, and can be selected and moved after they are drawn.
user selects the fill tool, and clicks on the drawing area. If the area is surrounded by lines in every direction a fill is applied to the area.
if the lines are moved after the fill is applied, the area of fill is changed accordingly.
Anyone has a nice idea, how to implement such algorithm? The main task is basically to determine the line segments surrounding a point. (and storing this information somehow, incase the lines are moved)
EDIT: an explanation image: (there can be other lines of course in the canvas, that do not matter for the fill algorithm)
EDIT2: a more difficult situation:
EDIT3: I have found a way to fill polygons with holes http://alienryderflex.com/polygon_fill/ , now the main question is, how do i find my polygons?
You're looking for a point location algorithm. It's not overly complex, but it's not simple enough to explain here. There's a good chapter on it in this book: http://www.cs.uu.nl/geobook/
When I get home I'll get my copy of the book and see if I can try anyway. There's just a lot of details you need to know about. It all boils down to building a DCEL of the input and maintain a datastructure as lines are added or removed. Any query with a mouse coord will simply return an inner halfedge of the component, and those in particular contain pointers to all of the inner components, which is exactly what you're asking for.
One thing though, is that you need to know the intersections in the input (because you cannot build the trapezoidal map if you have intersecting lines) , and if you can get away with it (i.e. input is few enough segments) I strongly suggest that you just use the naive O(n²) algorithm (simple, codeable and testable in less than 1 hour). The O(n log n) algorithm takes a few days to code and use a clever and very non-trivial data structure for the status. It is however also mentioned in the book, so if you feel up to the task you have 2 reasons to buy it. It is a really good book on geometric problems in general, so for that reason alone any programmer with interest in algorithms and datastructures should have a copy.
Try this:
http://keith-hair.net/blog/2008/08/04/find-intersection-point-of-two-lines-in-as3/
The function returns the intersection (if any) between two lines in ActionScript. You'll need to loop through all your lines against each other to get all of them.
Of course the order of the points will be significant if you're planning on filling them - that could be harder!
With ActionScript you can use beginFill and endFill, e.g.
pen_mc.beginFill(0x000000,100);
pen_mc.lineTo(400,100);
pen_mc.lineTo(400,200);
pen_mc.lineTo(300,200);
pen_mc.lineTo(300,100);
pen_mc.endFill();
http://www.actionscript.org/resources/articles/212/1/Dynamic-Drawing-Using-ActionScript/Page1.html
Flash CS4 also introduces support for paths:
http://www.flashandmath.com/basic/drawpathCS4/index.html
If you want to get crazy and code your own flood fill then Wikipedia has a decent primer, but I think that would be reinventing the atom for these purposes.

Minimax algorithm

I have a simple question regarding the Minimax algorithm: for example for the tic-tac-toe game, how do I determine the utility function's for each player plays? It doesn't do that automatically, does it? I must hard-code the values in the game, it can't learn them by itself, does it?
No, a MiniMax does not learn. It is a smarter version of a brute-force tree search.
Typically you would implement the utility function directly. In this case the algorithm would not learn how to play the game, it would use the information that you had explicitly hard-coded in the implementation.
However, it would be possible to use genetic programming (GP) or some equivalent technique to automatically derive a utility function. In this case you would not have to encode any explicit strategy. Instead the evolution would discover its own way of playing the game well.
You could either combine your minimax code and the GP code into a single (probably very slow) adaptive program, or you could run the GP first, find a good utility function and then add this function to your minimax code just as you would any hand-coded function.
Tic-Tac-Toe is small enough to run the game to the end and assign 1 for win, 0 for draw and -1 for lose.
Otherwise you have to provide a function which determines the value of a position heuristically. In chess for example a big factor is the value of the material, but also who controls the center or how easily the pieces can move.
As for learning, you can add weight factors to different aspects of the position and try to optimize those by repeatedly playing games.
How do determine the utility function for each play?
Carefully ;-) This article shows how a slightly flawed evaluation function (one for ex. which either doesn't go "deep" enough in looking ahead in the tree of possible plys, or one which fails to capture the relative strengh of some board positions) results in an overall weak algorithm (one that looses more often).
it can't learn them by itself, does it?
No, it doesn't. There are ways, however, to make the computer learn the relative strength of board positions. For example by looking into Donald Mitchie and his MENACE program you'll see how a stochastic process can be used to learn the board without any a priori knowledge but the rules of the game. The funny part is that while this can be implemented in computers, a few hundred colored beads and match boxes are all that is required, thanks to the relatively small size of the game space, and also thanks to various symmetries.
After learning such a cool way of teaching the computer how to play, we may not be so interested in going back to MinMax as applied to Tic-Tac-Toe. After all MinMax is a relatively simple way of pruning a decision tree, which is hardly needed with tic-tac-toe's small game space. But, if we must ;-) [go back to MinMax]...
We can look into the "matchbox" associated with the next play (i.e. not going deep at all), and use the percentage of beads associated with each square, as an additional factor. We can then evaluate a traditional tree, but only going, say 2 or 3 moves deep (a shallow look-ahead depth which would typically end in usually in losses or draws) and rate each next move on the basis of the simple -1 (loss), 0 (draw/unknown), +1 (win) rating. By then combining the beads percentage and the simple rating (by say addition, certainly not by multiplication), we are able to effectively use MinMax in a fashion that is more akin to the way it is used in cases when it is not possible to evaluate the game tree to its end.
Bottom line: In the case of Tic-Tac-Toe, MinMax only becomes more interesting (for example in helping us explore the effectiveness of a particular utility function) when we remove the deterministic nature of the game, associated with the easy evaluation the full tree. Another way of making the game [mathematically] interesting is to play with a opponent which makes mistakes...

Position of a point relative to a Bezier curve

I have a Bezier curve specified by 4 points. I need to know if a point is on the left side or right side of the Bezier curve. Can you suggest me an algorithm?
Edit: I'm sure that the way I generate the Bezier curve would not form loops.
Later edit I realized that my initial problem could be solved without using relative position. When I posted this question I was thinking that there is a mathematical formula for relative position similarly with checking if a point is in the interior of a circle. It seems that this is not possible. So I will accept the answer which will suggest a time efficient solution.
You can determine the closest point on the bezier curve with a pretty straightforward algorithm (related to k-subdivision. DeCastleju's Algorithm.) Look at the graphics gems if you need specifics.
At that point, even with loops, you can determine side-ness by determining if the vector to your tested point from the closest point is on the left of right hand of the vector that goes along the curve (velocity? - not sure of the correct term here...) of the bezier at the closest point you determined.
You can get -that- by cross product of the two vectors. Negative or positive will determine the handedness and which side of the line you are on.
Of course, in a loop the sideness will be defined as if you were a car driving down the line, would you be looking out the right or left window at the point as you go by... Not if you are to the right or left of the whole bezier squiggle. So it depends on how you define "sideness"
Sorry if my terms are off. Its been awhile since I had to do anything with Bezier's
It would be easier to draw a picture ;)
If you just want your object to follow the curve (as you say in your comment), why don't you just move your object with the parametric equation ? See this article
Here is math for cubic and quadratic Bezier curve implicitization.
I cannot remember the math at this late hour, but you'd probably want to use a subdivision algorithm for the curve to progressively refine it until the segments are 'straight' enough that you can treat them as line segments for the purposes of your determination.
You may be able to get a quicker answer by using the bounding polyhedra of the curve refinements to determine at which point your 'point' is outside all of the polyhedra, and then immediately flatten to line segments.
Assuming the point constrained to the curve, you must define one of the anchors as the start and the other as the end, then calculate a point that belongs to the curve and is in the middle (length's half)... that way you can say if the point is between the start and the middle or the middle and the end.
Is that what you want or am I totally lost?

How to simplify (reduce number of points) in KML?

I have a similar problem to this post. I need to display up to 1000 polygons on an embedded Google map. The polygons are in a SQL database, and I can render each one as a single KML file on the fly using a custom HttpHandler (in ASP.NET), like this http://alpha.foresttransparency.org/concession.1.kml .
Even on my (very fast) development machine, it takes a while to load up even a couple dozen shapes. So two questions, really:
What would be a good strategy for rendering these as markers instead of overlays once I'm beyond a certain zoom level?
Is there a publicly available algorithm for simplifying a polygon (reducing the number of points) so that I'm not showing more points than make sense at a certain zoom level?
For your second question: you need the Douglas-Peucker Generalization Algorithm
For your first question, could you calculate the area of a particular polygon, and relate each zoom level to a particular minimum area, so as you zoom in or out polygon's disappear and markers appear depending on the zoom level.
For the second question, I'd use Mark Bessey's suggestion.
I don't know much aobut KML, but I think the usual solution to question #2 involves iterating over the points, and deleting any line segments under a certain size. This will cause some "unfortunate" effects in some cases, but it's relatively fast and easy to do.
I would recommend 2 things:
- Calculate and combine polygons that are touching. This involves a LOT of processing and hard math, but I've done it so I know it's possible.
- Create your own overlay instead of using KML in PNG format, while you combine them in the previous suggestion. You'll have to create a LOT of PNGs but it is blazing fast on the client.
Good luck :)
I needed a solution to your #2 question a little bit ago and after looking at a few of the available line-simplification algorithms, I created my own.
The process is simple and it seems to work well, though it can be a bit slow if you don't implement it correctly:
P[0..n] is your array of points
Let T[n] be defined as the triangle formed by points P[n-1], P[n], P[n+1]
Max is the number of points you are trying to reduce this line to.
Calculate the area of every possible triangle T[1..n-1] in the set.
Choose the triangle T[i] with the smallest area
Remove the point P[i] to essentially flatten the triangle
Recalculate the area of the affected triangles T[n-1], T[n+1]
Go To Step #2 if the number of points > Max