PDA

Click to See Complete Forum and Search --> : Beziers



elstudion
08-13-2002, 06:55 AM
Hi!

I've made a drawingAPI that draws beziers with an unlimited number of controll points. Now, I've solved this with geometry and not algebra since I'm not that good at math. But this is very slow... To draw a bezier with four controll points it takes 60ms, while it takes less then 15ms with this code:



onClipEvent(enterFrame){
for (i=0;i<50;i++) this["d"+i].BezierPosition(bezier1, i/50)
}

...and...


Object.prototype.BezierPosition = function(bez, t){
t = Math.min(Math.max(t,0),1)

var c = 3* (bez.x1 - bez.x0)
var b = 3* (bez.x2 - bez.x1) - c
var a = bez.x3 - bez.x0 - c - b
this._x = a*t*t*t + b*t*t + c*t + bez.x0

c = 3* (bez.y1 - bez.y0)
b = 3* (bez.y2 - bez.y1) - c
a = bez.y3 - bez.y0 - c - b
this._y = a*t*t*t + b*t*t + c*t + bez.y0
}

(this code was written by someone at this board by I don't remember the name right now)

Well.. I could translate this to my drawingAPI, but this is only for four controll points... What about n controll points? With 5 controll points I know that the last line should be:


this._y = a*t*t*t*t + b*t*t*t + c*t*t + d*t + bez.y0

but other then that I don't understand much...

anyone?


.bobo

ericlin
08-13-2002, 09:31 AM
but this is only for four controll points... What about n controll points? With 5 controll points I know that the last line should be:

As I know, Bezier curve consists of 1 startPoint, 1 controlPoint for startPoint, 1 endPoint and 1 controlPoint for endPoint. There are 4 points.

I dont know what do you mean by "5 control points" ?

elstudion
08-13-2002, 10:20 AM
Originally posted by ericlin
As I know, Bezier curve consists of 1 startPoint, 1 controlPoint for startPoint, 1 endPoint and 1 controlPoint for endPoint. There are 4 points.

I dont know what do you mean by "5 control points" ?

I just posted a long replay to this, but when I was about to send it, it just dissapeared... =(

well, anyway. The basic rules for a Bezier will work with any number of points. curveTo in Flash MX is a Bezier using 3 points.

If you check http://www.elstudion.com/bobo/index2.html you can see my example of beziers using a random number of points from 3 to 8...

peace


.bobo

ericlin
08-13-2002, 10:58 AM
Oh, thank you.

I learn "Bezier curve" from Graph and Flash tutorial. When they talked about Bezier curve and showed examples, they always use 4 points model. So I thought Bezier curve is always 4 points.

If I had not replied, I wouldnt have got this corrected. Thank you.

tomsamson
08-22-2002, 11:01 AM
check out the file of august 11th
http://www.bit-101.com/lab.html

elstudion
08-22-2002, 03:16 PM
Originally posted by tomsamson
check out the file of august 11th
http://www.bit-101.com/lab.html

thanks, but it doesn't help me much...
first, I couldn't find any source code and
second and most important; that's not beziers... =)

I guess what he does is moving to the point in the middle of point A and B and curves to the middle of point B and C (using B as the controll point) and so on...

but thanks anyway! =)


.bobo

tomsamson
08-22-2002, 04:15 PM
the page i mentioned also has a source directory,but youīre right about the used method in the file i mentioned,sorry if it was no good for you.
so i guess Quadratic Bezier Vertex code/source like this one
http://www.were-here.com/forums/showthread.php?s=&threadid=154837
fails because of the same reason,right?

and what about
bezier segment code for subnodes?
like
http://www.were-here.com/forums/showthread.php?threadid=128935&highlight=bezier+segment

elstudion
08-22-2002, 05:13 PM
just by looking at the swf's i think that it isn't good for what i need... but I will investigate the .fla's as soon as i get a chance...

even if it doesn't help me it is interesting reading...

thanks!


.bobo

tomsamson
08-22-2002, 06:10 PM
Originally posted by elstudion
just by looking at the swf's i think that it isn't good for what i need... but I will investigate the .fla's as soon as i get a chance...

even if it doesn't help me it is interesting reading...

thanks!


.bobo


no prob,by the way,the "misfitting file i mentioned in my first post can be downloaded here:
http://www.bit-101.com/flafiles/020811.fla

(iīm working on a simple 3d editor where you can set points,select two to connect them and select several ones to build a shape or draw curved things and that source inspired me to do that,so i still like it :) )


check out the vapor example here (press on render)
http://www.outmoded.com/index.php
thatīs the most impressive bezier thing iīve seen done in flash up to date :)

Dickee
08-23-2002, 02:49 AM
This is a long post, but I thought it would be wise to take the logic through the powers to explain the syntax more clearly.
Firstly, I'll post an example by ahab that will show you expansion of 2 binomials using the FOIL method from this thread:

Bezier curves - http://board.flashkit.com/board/showthread.php?threadid=58629

/////////////////////////////////

-- To get the Bernstein basis functions, 1 can be rewritten like this:

1 = t + [1 - t]

-- use this substitution to square 1, resulting in a quadratic equation:

1^2 = (t + [1 - t])(t + [1 - t])

-- FOIL out the 2 binomials -- (First, Outside, Inside, Last):

1 = t^2 + t(1 - t) + t(1 - t) + (1 - t)^2

-- combine like terms --

1 = t^2 + 2t(1 - t) + (1 - t)^2

/////////////////////////////////

Now, as the next link will advise, the FOIL method is a particular example of the Distributive Property for the expansion of polynomials:

http://mathforum.org/library/drmath/view/57480.html

/////////////////////////////////

Now we'll use the Distributive Property to expand the cube of 1, resulting in a cubic equation:

1^3 = (t + [1 - t])(t + [1 - t])(t + [1 - t])

First, expand the product of the first 2 factors, resulting in the same quadratic equation as in ahab's example above:

(t + [1 - t])(t + [1 - t]) = t^2 + t*[1-t] + [1-t]*t + [1-t]^2

Below is the same right operand as above, split into our basis functions, each found between ||-||:

= ~B0~||(t^2)|| + ~B1~||( t*[1-t] + [1-t]*t)|| + ~B2~||([1-t]^2)||

Then combine like terms and list:

B0(t) = t^2
B1(t) = 2*t*[1-t]
B2(t) = [1-t]^2

Now replace the first 2 factors with the above expansion, and expand the product of that expansion and the 3rd factor:

(t^2 + 2*(t*[1-t]) + [1-t]^2)(t+[1-t])
= t^3 + t^2*[1-t] + (2*(t*[1-t])*t) + (2*(t*[1-t])*[1-t]) + ([1-t]^2)*t + [1-t]^3

= ~B0~||(t^3)|| + ~B1~||(t^2*[1-t]) + (2*(t*[1-t])*t)|| + ~B2~||(2*(t*[1-t])*[1-t]) + (([1-t]^2)*t)|| + ~B3~||([1-t]^3)||

B0(t) = t^3
B1(t) = 3*t^2*[1-t]
B2(t) = 3*t*[1-t]^2
B3(t) = [1-t]^3

/////////////////////////////////

Now we'll take the equation to the 4th power, resulting in a quartic equation:

1^4 = (t + [1 - t])(t + [1 - t])(t + [1 - t])(t + [1 - t])

Using the cubic results, replace the first 3 factors, then find the product of that equation and the 4th factor:

((t^3) + (3*t^2*[1-t]) + (3*t*[1-t]^2) + [1-t]^3)(t+[1-t])
= (t^4) + (t^3*[1-t]) + ((3*t^2*[1-t])*t) + ((3*t^2*[1-t])*[1-t]) + ((3*t*[1-t]^2)*t) + ((3*t*[1-t]^2)*[1-t]) +( [1-t]^3*t) +( [1-t]^3*[1-t])

= ~B0~||(t^4)|| + ~B1~||(t^3*[1-t]) + ((3*t^2*[1-t])*t)|| + ~B2~||((3*t^2*[1-t])*[1-t]) + ((3*t*[1-t]^2)*t)|| + ~B3~||((3*t*[1-t]^2)*[1-t]) +( [1-t]^3*t)|| +~B4~||( [1-t]^3*[1-t])||

B0(t) = t^4
B1(t) = 4*t^3*[1-t]
B2(t) = 6*t^2*[1-t]^2
B3(t) = 4*t*[1-t]^3
B4(t) = [1-t]^4

/////////////////////////////////

Finally, we'll take the equation to the 5th power, resulting in a quintic equation:

1^5 = (t + [1 - t])(t + [1 - t])(t + [1 - t])(t + [1 - t])(t + [1 - t])

Again, we'll now use the quartic results to find the product of that equation and the 5th factor:

((t^4) + (4*t^3*[1-t]) + (6*t^2*[1-t]^2) + (4*t*[1-t]^3) + ([1-t]^4))(t+[1-t])
= (t^5) + (t^4*[1-t]) + ((4*t^3*[1-t])*t) + ((4*t^3*[1-t])*[1-t]) + ((6*t^2*[1-t]^2)*t) + ((6*t^2*[1-t]^2)*[1-t]) + ((4*t*[1-t]^3)*t) + ((4*t*[1-t]^3)*[1-t]) + ([1-t]^4*t) + ([1-t]^4*[1-t])

= ~B0~||(t^5)|| + ~B1~||(t^4*[1-t]) + ((4*t^3*[1-t])*t)|| + ~B2~||((4*t^3*[1-t])*[1-t]) + ((6*t^2*[1-t]^2)*t)|| + ~B3~||((6*t^2*[1-t]^2)*[1-t]) + ((4*t*[1-t]^3)*t) + ~B4~||((4*t*[1-t]^3)*[1-t]) + (([1-t]^4)*t) + ~B5~||(([1-t]^4)*[1-t])||

B0(t) = t^5
B1(t) = 5*t^4*[1-t]
B2(t) = 10*t^3*[1-t]^2
B3(t) = 10*t^2*[1-t]^3
B4(t) = 5*t*[1-t]^4
B5(t) = [1-t]^5

/////////////////////////////////

Of course, you can extrapolate this syntax to as many powers as required, although you may find that cpu usage may rise with the extra complexity. Each basis function represents the arc between 2 points, resulting in (n)arcs and (n+1)points. I'll post the main code for the quintic bezier below ... you can download the quadratic, cubic and quartic bezier examples by Den Ivanov, written for Flash5, from Flashkit's download area. I'll also provide links to the quintic swf/fla below (the code is still Flash5, although published in FlashMX) ... BTW, many thanks to Den for providing the original source code.

After completing this post, I read your new message that states you are working on a 3d version. owel, you may find this post useful ... Den also has a 3d bezier version which I haven't yet explored, posted at his site ... http://flash.onego.ru ...under 'my new Flash MX stuff'.

--edit--

I took a quick look at Den's 3dsplines code, and found that he's used 'curveTo' to draw the splines ... so the integrated quadratic 3-point method has been utilized.

http://members.shaw.ca/flashmath101/quinticBezier.swf
http://members.shaw.ca/flashmath101/quinticBezier.fla


// quinticBezier
// adapted from: Den Ivanov - http://flash.onego.ru

// Bernstein basis functions
function B1 (t) {
return (t * t * t * t * t);
}
function B2 (t) {
return (5 * t * t * t * t * (1 - t));
}
function B3 (t) {
return (10 * t * t * t * (1 - t) * (1 - t));
}

function B4 (t) {
return (10 * t * t * (1 - t) * (1 - t) * (1 - t));
}

function B5 (t) {
return (5 * t * (1 - t) * (1 - t) * (1 - t) * (1 - t));
}

function B6 (t) {
return ((1 - t) * (1 - t) * (1 - t) * (1 - t) * (1 - t));
}

// draw spline routine : called from RedrawClip
function DrawSpline () {
count = 0;
// change this for smooth line
detailBias = 1/30;
level = 1;
do {
x = cP1._x*B1(count)+cP2._x*B2(count)+cP3._x*B3(count) +cP4._x*B4(count)+cP5._x*B5(count)+cP6._x*B6(count );
y = cP1._y*B1(count)+cP2._y*B2(count)+cP3._y*B3(count) +cP4._y*B4(count)+cP5._y*B5(count)+cP6._y*B6(count );
if (level>1) {
attachMovie("line", "line"+level, level+10);
_root["line"+level]._x = x;
_root["line"+level]._y = y;
_root["line"+level]._rotation = Math.atan2(yold-y, xold-x)*180/(Math.PI);
_root["line"+level]._xscale = _root["line"+level]._yscale = Math.sqrt((xold-x)*(xold-x)+(yold-y)*(yold-y));
}
yold = y;
xold = x;
++level;
count += detailBias;
} while (count<=1);
}

// main init : put 6 control point to stage
for (i=1; i<=6; i++) {
attachMovie("cdot", "cP"+i, i);
_root["cP"+i]._x = random(540);
_root["cP"+i]._y = random(400);
_root["cP"+i].n = i;
}
stop();

Richard
[Edited by Dickee on 08-23-2002 at 02:21 PM]

elstudion
08-23-2002, 03:14 AM
Thank you so very much... I think I love you ;)

I've been desperate for that math thing so long, but havn't been able to find it anywhere!

But one thing; you say that the cpu usage will rise if you use many controllpoints... Is it possible that it will be faster to use geometry if you're using many controllpoints?

Using 8 points with geometry takes ~250ms, but it will too get slower and slower...

If you have a 3d enviroment allready, it would be easy enough to do a 3d bezier... to calculate the z you do exactly as you did with x and y... so there would be no difference that I know of...

I still like my drawingAPI for the beziers with unlimited controlpoints, but maybe it will be hard to implement the math if I'm sticking to it beeing unlimited....? What do you think?

as a little selfpromotion once more:
http://www.elstudion.com/bobo/index2.html
for my bezier thing... There is also another more basic at:
http://www.elstudion.com/bobo/


thanks everyone for helping me out! =) =) =)


.bobo

Dickee
08-23-2002, 03:29 AM
http://www.elstudion.com/bobo/


That's just lovely! Whatever you're doing ... keep doing it!

I didn't do any speed tests on the quintic ... I just noticed a speed decrease in comparison to Den's quartic example.

Have fun!

Richard

tomsamson
08-23-2002, 09:42 PM
Originally posted by elstudion


If you have a 3d enviroment allready, it would be easy enough to do a 3d bezier... to calculate the z you do exactly as you did with x and y... so there would be no difference that I know of...

I still like my drawingAPI for the beziers with unlimited controlpoints, but maybe it will be hard to implement the math if I'm sticking to it beeing unlimited....? What do you think?


yep,i implemented the bezier part now,quite fun to play around with it,but quite useless unless i find a way to save the generated models (maybe as xml)...
about your bezier thingy: thereīs no way around,it will always get slower the more controlpoints you add,but congrats on it,nevertheless fast,smooth,nice one :)

elstudion
08-24-2002, 05:23 AM
Originally posted by tomsamson

yep,i implemented the bezier part now,quite fun to play around with it,but quite useless unless i find a way to save the generated models (maybe as xml)...
about your bezier thingy: thereīs no way around,it will always get slower the more controlpoints you add,but congrats on it,nevertheless fast,smooth,nice one :)

Can't you just save the controll points and then generate the beziers again at runtime? Or mabe that's what you had in mind all the time...

What I ment about my beziers and the speed of them was f it eventually would be faster to calculate them with geometry instead of algebra? I don't think so though... When I've implemented the algebra into my project I will run some tests and get back to you...

thanks for helping me out and thank you Dickee for liking what I've done... =)

.b

tomsamson
08-27-2002, 12:21 PM
Originally posted by elstudion

Originally posted by tomsamson

yep,i implemented the bezier part now,quite fun to play around with it,but quite useless unless i find a way to save the generated models (maybe as xml)...
about your bezier thingy: thereīs no way around,it will always get slower the more controlpoints you add,but congrats on it,nevertheless fast,smooth,nice one :)

Can't you just save the controll points and then generate the beziers again at runtime? Or mabe that's what you had in mind all the time...
yes,youīre right,thatīs what i want to do.iīve got everything working (the drawing mode,the different viewpoint windows etc.and the output window that creates a string with the positions of all controllpoints),except the possibiltiy to save the generated output.
it wouldnīt be any problem if iīd use that app like thingy in a browser and send the generated data via php/xml to a server,but i want this to be used as offline/standalone app and i donīt have a solution how to save that for this case...

(but i wonīt give up before finding a solution after coming up to this point :) )



Originally posted by elstudion

What I ment about my beziers and the speed of them was f it eventually would be faster to calculate them with geometry instead of algebra? I don't think so though... When I've implemented the algebra into my project I will run some tests and get back to you...

thanks for helping me out and thank you Dickee for liking what I've done... =)

.b [/B]

no problem,always with joy :) ,
to geometry instead of algebra way?
iīd say it wonīt change a lot but iīm not sure as i didnīt do direct comparisons with the same settings,so iīm looking forward to your comparion results :)

brutfood
09-02-2002, 10:51 PM
What a wonderful thread! - I found it just at the time I wanted to know all about Bezier curves, and it told me everything I wanted to know.

tomsamson: I liked the August 11th Example. I too want to fit a curve around a set of points. I can see that the technique used here is quite simple.

Actually I want to generate a smooth curve from a dragged mouse path. Similar to the MX pencil tool. I'm thinking about filtering the many points obtained from this drag, to just a few representative ones. Then treating these as control points - as you have done. My filtering will retain more points where path of points changes direction more rapidly (and less for smoother sections) - this seems sensible. Anyone done this already?

Dickee: Thanks, this was VERY informative. This is what I was looking for. By the way, rather than doing all that multiplication of polynomials, you just have to use successive lines of pascal's triangle:-

1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1

(Can also be derived using 'combinations' formula)

So the 6th power equation is:

B0(t) = t^6
B1(t) = 6*t^5*(1-t)
B2(t) = 15*t^4*(1-t)^2
B3(t) = 20*t^3*(1-t)^3
B4(t) = 15*t^2*(1-t)^4
B5(t) = 6*t*(1-t)^5
B6(t) = (1-t)^6

I just love mathematical patterns like this :)

brutfood
09-03-2002, 06:54 AM
I'm having fun with Bezier curves, but there's something I've yet to figure out.

Suppose I have two quadratic bezier curves on the screen. How do I determine their points of intersection?

What's stumpted me is that the bezier equations are parametric (in terms of t). What I need is an equalty in terms of both x and y (I suspect this will boil down to solving a quadratic).

Help anyone?

Dickee
09-05-2002, 07:58 AM
Hey brutfood et al!

Well, I've been researching 'determining intersection of two Bezier curves', with very little information to glean from the net. The links I've provided below will advise that the solution to this problem is very complex ... way over my head, using calculus integration, partial derivitives, etc. to return accurate results.

So, what I've produced is an approximation technique based on the increment of 't' and a tolerance factor, both adjustable onscreen. However, not only does this technique derive results in an inappropriate manner (by finding the mean of a pair of points from each curve's near-point that lies within the tolerance factor), but also I haven't followed any of the procedures suggested in the links ... let the kludge banners fly!

I've utilized Den's Flash 5 coding for this file, but perhaps a more efficient solution could be found with either Robert Penner's or Timothee Groleau's cubic Bezier recursion methods. The last two links below take you to their respective solutions.

I may indeed be on the right track with my file (except for the mean kludge finish!) ... perhaps I may find a way to further refine my coordinates by implementing the hint from the quote below.

Please explore/alter my file to see if I'm missing something that's glaring, but presently hiding from me, to achieve more consistent and accurate results. Or perhaps the links will spill the beans for you to produce a more precise algorithm applying de-Casteljau, NURBS or some other method!

http://members.shaw.ca/flashmath101/cubicBezierIntersect.swf
http://members.shaw.ca/flashmath101/cubicBezierIntersect.fla

From the 1st link below ... he tempts us with the solution thoughout the page, then leaves us hanging without providing the algorithm:


So if "there are no good, general methods for solving systems of more than one nonlinear equation," then what hope do we have in this matter of Bezier intersection? The key is to recognize that we need a good, specific (as opposed to general) method, specific to the Bezier equations. Indeed, there is another algorithm altogether, which avoids the inherent numerical confusion of bisection, and which allows us to find the peaks, no more and no less. I am not going to reveal that unpublished algorithm here, but I will give you a hint: one avoids the mire of a swamp by reformulating it as a large set of problems that have a small number of fast, closed-form solutions.


http://truetex.com/bezint.htm
http://www.magic-software.com/Community/TechPosts/IntersectionOfBezierCurves.Mar2001.txt
http://www.cs.unc.edu/~yanghua/Assignment3.htm
http://www.math.niu.edu/~rusin/known-math/99/meets
http://www.tinaja.com/cubic01.asp
http://www.gamasutra.com/features/19991027/deloura_01.htm
http://www.cs.huji.ac.il/~arik/java/ex2/
http://www.tinaja.com/text/bezchord.html
http://www.engineering.uiowa.edu/~amalek/papers/CAD1.pdf
http://www.magic-software.com/Documentation/IntersectionOfEllipses.pdf
http://www.whizkidtech.net/bezier/circle/

http://chattyfig.figleaf.com/ezmlm/ezmlm-cgi?1:msp:35110:dgldhpinefbenjodddmo // Penner
http://www.timotheegroleau.com/Flash/articles/cubic_bezier/cubic_bezier_in_flash.htm // Groleau

Richard
[Edited by Dickee on 09-05-2002 at 08:34 AM]

brutfood
09-05-2002, 09:15 AM
Thanks Dickie. I suspected it wasn't easy and that I may need to iterate to an approximation.

I devised a quick and dirty method. (but haven't tested it extensively yet). My method only needs be as accurate as the eye can perceive on a screen.

I know how to arrive at the intersection of a quadratic bezier curve and a straight line.

y=mx+c
y=at^2+bt+d
x=et^2+ft+g

so solve:- (a-me)t^2+(b-mf)t+(d-mg-c)=0

So my solution is to approximate the second quadratic bezier curve by straight line segments.

(by the way - I'm using quadratic curves so I can utilise curveTo to draw them).

Dickee
09-12-2002, 02:14 AM
Hey brutfood!

OK, I'm not finished yet, but I thought I would post this as is to see if anyone else can come up with more or better code to increase intersect accuracy. I've switched to Lifaros' (we're-here forum id) 'bezierLibLifaros.as' to map quadratic bezier segments drawn with Flash's 'curveTo' function, since you stated that your explorations will concentrate on this function.

I'm using arrays, with each quadratic bezier populating it's array with 120 points along it's path, and the length of each bezier segment determining the accuracy factor, which is used in an equation to place intersect flags. At present, results range from quite accurate, to no flags showing in spite of actual intersections onstage, to many flags showing false but close coordinates due to 'level' and 'tolerance' settings, to 'over the time limit, freeze the progy' if 'level' is set too high!

I've used frame-based animation to show the progression through the coordinates, so speed of the app to reach the final computation is slower than what could be accomplished. Both 'level' and 'factor' can be adjusted onscreen, so please experiment with different values to see if more accuracy can be obtained. After altering the variables, clicking on any of the control points will start the animation and preserve the bezier positioning (the points are also draggable), and clicking the button will refresh with new randomly placed control points.

I've also included Gary Fixler's 'nearBezFixler.as' in the zip file, which I plan to explore next to increase intersect flag accuracy. His .as file uses recursive bisection of the bezier curve to find the nearest point to the target point, and I think it will be adaptable for 2 bezier curves as well.

I've also been working on a new cubicBezierIntersect.fla, which breaks up the cubic into quadratic segments, drawn with 'curveTo'. But I want to increase accuracy on the quadratic file first, then apply the algorithm to the cubic file, since the more complex cubic file will also need to flag 'self-intersecting' points.

--edit--

I've been exploring various scenarios, and I made a file that uses 'hitTest' instead of array comparison. The file also includes commented-out code on frame 2 using Gary Fixler's 'nearBezFixler.as' (found in the zip above) that uses trace for the results. You can compare both ways in the authoring environment by uncommenting the code, but you'll need to modify 'level' to about 40-50 instead of 200, or the file will stall. I haven't explored factoring 'level' via 'quadLength' to get more accurate results, thus this edit rather than a new post.

The hitTest method's code can be simplified much more than this ... eg. no need for the includes if 'quadLength' is not used to factor 'level'. HitTest is proving to be much faster, but not as accurate ... I've used 'false' in the arguments, so there is no fudging of the points. We muster onward ...

..edit2..

Still not satisfied with accuracy, so I've just updated the file from v7 to v10 ... but it's much better using a level factor based on each bezier's length. Still using the 'hitTest' routine, and I've updated the commented-out 'nrstBezPt()' code, but it doesn't work as yet. Also, I've updated the Fixler.as file, so I've zipped it up in v10.

http://members.shaw.ca/flashmath101/quadBezierIntersect10.swf
http://members.shaw.ca/flashmath101/quadBezierIntersect10.zip

Richard
[Edited by Dickee on 09-15-2002 at 02:22 AM]

AmiFlashKit
11-21-2008, 11:32 AM
This is a long post, but I thought it would be wise to take the logic through the powers to explain the syntax more clearly.
Firstly, I'll post an example by ahab that will show you expansion of 2 binomials using the FOIL method from this thread:

Bezier curves - http://board.flashkit.com/board/showthread.php?threadid=58629

/////////////////////////////////

-- To get the Bernstein basis functions, 1 can be rewritten like this:

1 = t + [1 - t]

-- use this substitution to square 1, resulting in a quadratic equation:

1^2 = (t + [1 - t])(t + [1 - t])

-- FOIL out the 2 binomials -- (First, Outside, Inside, Last):

1 = t^2 + t(1 - t) + t(1 - t) + (1 - t)^2

-- combine like terms --

1 = t^2 + 2t(1 - t) + (1 - t)^2

/////////////////////////////////

Now, as the next link will advise, the FOIL method is a particular example of the Distributive Property for the expansion of polynomials:

http://mathforum.org/library/drmath/view/57480.html

/////////////////////////////////

Now we'll use the Distributive Property to expand the cube of 1, resulting in a cubic equation:

1^3 = (t + [1 - t])(t + [1 - t])(t + [1 - t])

First, expand the product of the first 2 factors, resulting in the same quadratic equation as in ahab's example above:

(t + [1 - t])(t + [1 - t]) = t^2 + t*[1-t] + [1-t]*t + [1-t]^2

Below is the same right operand as above, split into our basis functions, each found between ||-||:

= ~B0~||(t^2)|| + ~B1~||( t*[1-t] + [1-t]*t)|| + ~B2~||([1-t]^2)||

Then combine like terms and list:

B0(t) = t^2
B1(t) = 2*t*[1-t]
B2(t) = [1-t]^2

Now replace the first 2 factors with the above expansion, and expand the product of that expansion and the 3rd factor:

(t^2 + 2*(t*[1-t]) + [1-t]^2)(t+[1-t])
= t^3 + t^2*[1-t] + (2*(t*[1-t])*t) + (2*(t*[1-t])*[1-t]) + ([1-t]^2)*t + [1-t]^3

= ~B0~||(t^3)|| + ~B1~||(t^2*[1-t]) + (2*(t*[1-t])*t)|| + ~B2~||(2*(t*[1-t])*[1-t]) + (([1-t]^2)*t)|| + ~B3~||([1-t]^3)||

B0(t) = t^3
B1(t) = 3*t^2*[1-t]
B2(t) = 3*t*[1-t]^2
B3(t) = [1-t]^3

/////////////////////////////////

Now we'll take the equation to the 4th power, resulting in a quartic equation:

1^4 = (t + [1 - t])(t + [1 - t])(t + [1 - t])(t + [1 - t])

Using the cubic results, replace the first 3 factors, then find the product of that equation and the 4th factor:

((t^3) + (3*t^2*[1-t]) + (3*t*[1-t]^2) + [1-t]^3)(t+[1-t])
= (t^4) + (t^3*[1-t]) + ((3*t^2*[1-t])*t) + ((3*t^2*[1-t])*[1-t]) + ((3*t*[1-t]^2)*t) + ((3*t*[1-t]^2)*[1-t]) +( [1-t]^3*t) +( [1-t]^3*[1-t])

= ~B0~||(t^4)|| + ~B1~||(t^3*[1-t]) + ((3*t^2*[1-t])*t)|| + ~B2~||((3*t^2*[1-t])*[1-t]) + ((3*t*[1-t]^2)*t)|| + ~B3~||((3*t*[1-t]^2)*[1-t]) +( [1-t]^3*t)|| +~B4~||( [1-t]^3*[1-t])||

B0(t) = t^4
B1(t) = 4*t^3*[1-t]
B2(t) = 6*t^2*[1-t]^2
B3(t) = 4*t*[1-t]^3
B4(t) = [1-t]^4

/////////////////////////////////

Finally, we'll take the equation to the 5th power, resulting in a quintic equation:

1^5 = (t + [1 - t])(t + [1 - t])(t + [1 - t])(t + [1 - t])(t + [1 - t])

Again, we'll now use the quartic results to find the product of that equation and the 5th factor:

((t^4) + (4*t^3*[1-t]) + (6*t^2*[1-t]^2) + (4*t*[1-t]^3) + ([1-t]^4))(t+[1-t])
= (t^5) + (t^4*[1-t]) + ((4*t^3*[1-t])*t) + ((4*t^3*[1-t])*[1-t]) + ((6*t^2*[1-t]^2)*t) + ((6*t^2*[1-t]^2)*[1-t]) + ((4*t*[1-t]^3)*t) + ((4*t*[1-t]^3)*[1-t]) + ([1-t]^4*t) + ([1-t]^4*[1-t])

= ~B0~||(t^5)|| + ~B1~||(t^4*[1-t]) + ((4*t^3*[1-t])*t)|| + ~B2~||((4*t^3*[1-t])*[1-t]) + ((6*t^2*[1-t]^2)*t)|| + ~B3~||((6*t^2*[1-t]^2)*[1-t]) + ((4*t*[1-t]^3)*t) + ~B4~||((4*t*[1-t]^3)*[1-t]) + (([1-t]^4)*t) + ~B5~||(([1-t]^4)*[1-t])||

B0(t) = t^5
B1(t) = 5*t^4*[1-t]
B2(t) = 10*t^3*[1-t]^2
B3(t) = 10*t^2*[1-t]^3
B4(t) = 5*t*[1-t]^4
B5(t) = [1-t]^5

/////////////////////////////////

Of course, you can extrapolate this syntax to as many powers as required, although you may find that cpu usage may rise with the extra complexity. Each basis function represents the arc between 2 points, resulting in (n)arcs and (n+1)points. I'll post the main code for the quintic bezier below ... you can download the quadratic, cubic and quartic bezier examples by Den Ivanov, written for Flash5, from Flashkit's download area. I'll also provide links to the quintic swf/fla below (the code is still Flash5, although published in FlashMX) ... BTW, many thanks to Den for providing the original source code.

After completing this post, I read your new message that states you are working on a 3d version. owel, you may find this post useful ... Den also has a 3d bezier version which I haven't yet explored, posted at his site ... http://flash.onego.ru ...under 'my new Flash MX stuff'.

--edit--

I took a quick look at Den's 3dsplines code, and found that he's used 'curveTo' to draw the splines ... so the integrated quadratic 3-point method has been utilized.

http://members.shaw.ca/flashmath101/quinticBezier.swf
http://members.shaw.ca/flashmath101/quinticBezier.fla


// quinticBezier
// adapted from: Den Ivanov - http://flash.onego.ru

// Bernstein basis functions
function B1 (t) {
return (t * t * t * t * t);
}
function B2 (t) {
return (5 * t * t * t * t * (1 - t));
}
function B3 (t) {
return (10 * t * t * t * (1 - t) * (1 - t));
}

function B4 (t) {
return (10 * t * t * (1 - t) * (1 - t) * (1 - t));
}

function B5 (t) {
return (5 * t * (1 - t) * (1 - t) * (1 - t) * (1 - t));
}

function B6 (t) {
return ((1 - t) * (1 - t) * (1 - t) * (1 - t) * (1 - t));
}

// draw spline routine : called from RedrawClip
function DrawSpline () {
count = 0;
// change this for smooth line
detailBias = 1/30;
level = 1;
do {
x = cP1._x*B1(count)+cP2._x*B2(count)+cP3._x*B3(count) +cP4._x*B4(count)+cP5._x*B5(count)+cP6._x*B6(count );
y = cP1._y*B1(count)+cP2._y*B2(count)+cP3._y*B3(count) +cP4._y*B4(count)+cP5._y*B5(count)+cP6._y*B6(count );
if (level>1) {
attachMovie("line", "line"+level, level+10);
_root["line"+level]._x = x;
_root["line"+level]._y = y;
_root["line"+level]._rotation = Math.atan2(yold-y, xold-x)*180/(Math.PI);
_root["line"+level]._xscale = _root["line"+level]._yscale = Math.sqrt((xold-x)*(xold-x)+(yold-y)*(yold-y));
}
yold = y;
xold = x;
++level;
count += detailBias;
} while (count<=1);
}

// main init : put 6 control point to stage
for (i=1; i<=6; i++) {
attachMovie("cdot", "cP"+i, i);
_root["cP"+i]._x = random(540);
_root["cP"+i]._y = random(400);
_root["cP"+i].n = i;
}
stop();

Richard
[Edited by Dickee on 08-23-2002 at 02:21 PM]

Hello everyone,
i'm new to this forums and to actionscript3.
I saw that this code is actionscript 2. Can someone translate to Actionscript 3? Moreover, the vars are not declared, so i don't know what kind of vars are: Number, DOuble.... etc...

Thank you very nuch.