Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 30 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
30
Dung lượng
309,47 KB
Nội dung
401 PARTICLE SYSTEMS 9. Compile and run the program. You will see something like what is shown in Figure 10-3. Figure 10-3. The particles now have random color, scale, and opacity. 10. So the particle generator is in place and does a pretty good job of randomizing our particles, but at this point, they’re static. We need to make them move. Let’s start by adding age and life span to each particle. Open the L]npe_ha*t]ih*_o file, and add the following lines of code before the L]npe_ha$% constructor. These are two simple, publicly accessible properties that will be used to track a particle’s age and life span. lq^he_ejp=cawcap7oap7y lq^he_ejpHebaOl]jwcap7oap7y 11. Back in I]ejL]ca*t]ih*_o, add the following two lines at the bottom of the I]ejL]ca$% con- structor. These lines of code will set up an event listener for our Peian storyboard and start the storyboard running. Ikra*?kilhapa`'9jasArajpD]j`han$IkraL]npe_hao%7 Ikra*>acej$%7 402 CHAPTER 10 12. Inside the ?na]paL]npe_hao$% function, add the following line, which will create a random life span between 0 and 120 frames for each particle as it is created. At 30 frames per second, that should be a maximum of 4 seconds that any given particle is on the screen. l]npe_ha*HebaOl]j9N]j`*Jatp$ ,%7 13. The IkraL]npe_hao$% event handler is shown following. This code uses the bkna]_d loop to step through each l]npe_ha in the L]npe_hao Heop, increment the age, and test to see if the particle has reached its life span. If so, the particle is removed from the main canvas. lner]parke`IkraL]npe_hao$k^fa_poaj`an(Arajp=ncoa% w bkna]_d$L]npe_hal]npe_haejL]npe_hao% w l]npe_ha*=ca'9-7 eb$l]npe_ha*=ca:9l]npe_ha*HebaOl]j%w H]ukqpNkkp*?deh`naj*Naikra$l]npe_ha%7 y y Ikra*>acej$%7 y 14. Compile and run the project. The particles will be drawn, and after a second or so, will start disappearing from the screen until they’re all gone. 15. Each time a particle dies, we’ll create a new one. To do this, we’ll first need to make a change to the IkraL]npe_hao$% code, however. The bkna]_d loop locks up the enumeration of our L]npe_hao Heop. When a particle dies, it’s not enough to remove it from the main canvas; we should also pull it out of our Heop. Since the enumeration is locked, attempting to change the Heop length while the loop is running would cause an exception. Instead, we’ll change that to a basic bkn loop. After the change, the IkraL]npe_hao$% function should look like the follow- ing: lner]parke`IkraL]npe_hao$k^fa_poaj`an(Arajp=ncoa% w bkn$ejpe9,7e8L]npe_hao*?kqjp7e''% w L]npe_haoWeY*=ca'9-7 eb$L]npe_haoWeY*=ca:9L]npe_haoWeY*HebaOl]j% w H]ukqpNkkp*?deh`naj*Naikra$L]npe_haoWeY%7 y y Ikra*>acej$%7 y 403 PARTICLE SYSTEMS 16. Now, we can add code inside the eb logic to remove the dead particle from the Heop and generate a new one on the screen. The relevant new code is shown in bold in the following listing: lner]parke`IkraL]npe_hao$k^fa_poaj`an(Arajp=ncoa% w bkn$ejpe9,7e8L]npe_hao*?kqjp7e''% w L]npe_haoWeY*=ca'9-7 eb$L]npe_haoWeY*=ca:9L]npe_haoWeY*HebaOl]j% w H]ukqpNkkp*?deh`naj*Naikra$L]npe_haoWeY%7 L]npe_hao*Naikra$L]npe_haoWeY%7 ?na]paL]npe_hao$-%7 y y Ikra*>acej$%7 y 17. If you run the program at this point, your particles will be drawn on the screen, and as a par- ticle dies, a new one will be generated to replace it. All that’s left to do is to add a little code to make them move. Inside the L]npe_ha*t]ih*_o file, add the following variable declaration before the I]ejL]ca$% constructor: lq^he_LkejpRahk_epu7 18. Inside the ?na]paL]npe_ha$% function in the I]ejL]ca*t]ih*_o file, add the following code to create random values for the x and y velocity values of each particle. Just to make sure none of the particles are standing still, test for 0 values and assign them a new value to keep them moving: l]npe_ha*Rahk_epu*T9N]j`*Jatp$)1($ejp%1%7 l]npe_ha*Rahk_epu*U9N]j`*Jatp$)1($ejp%1%7 eb$l]npe_ha*Rahk_epu*T99,%l]npe_ha*Rahk_epu*T9.7 eb$l]npe_ha*Rahk_epu*U99,%l]npe_ha*Rahk_epu*U9.7 19. Inside the IkraL]npe_hao$% function, add the following two lines of code just before the line that increments the particle’s age: ?]jr]o*OapHabp$L]npe_haoWeY(?]jr]o*CapHabp$L]npe_haoWeY%' L]npe_haoWeY*Rahk_epu*T%7 ?]jr]o*OapPkl$L]npe_haoWeY(?]jr]o*CapPkl$L]npe_haoWeY%' L]npe_haoWeY*Rahk_epu*U%7 Press F5 to compile and run the project. The particles will be drawn and move about the screen ran- domly. Each time a particle dies, another will be generated to take the place of the recently deceased. The final version of this code is available in the BasicParticleSystemsCompleted project. 404 CHAPTER 10 If you were so inclined, you might consider adding a “dying” storyboard animation to the L]npe_ha* t]ih file, perhaps one that quickly shrinks the particle to nothing. When the particle reaches the end of its life span, the dying animation would be played, and upon completion, the particle would be removed from the L]npe_hao Heop and main canvas. Emitters Emitters are just what their name implies: objects that emit particles. The example project we just built didn’t make use of a specific emitter for the particle, but emitters are relatively easy to implement. Let’s take a look at how we can make use of an emitter. 1. Open the ParticleEmitters project. This project contains the same I]ejL]ca*t]ih and particle as the last project did, but also includes an object called Aieppan. The XAML for the Aieppan object is shown following—it’s nothing more than a 100100 canvas with a gray background so you can see it on the screen. The reason why we want to be able to see it in this case is because the canvas is draggable. I’ve already added the dragging code to the Aieppan*t]ih*_o file, and the two lines of code necessary to instance the object on the main canvas. You can compile and run the project and see that the gray canvas can be dragged around the application. 8Qoan?kjpnkht6?h]oo9L]npe_haAieppano*Aieppan tihjo9dppl6++o_dai]o*ie_nkokbp*_ki+sejbt+.,,2+t]ih+lnaoajp]pekj tihjo6t9dppl6++o_dai]o*ie_nkokbp*_ki+sejbt+.,,2+t]ih Se`pd9-,,Daecdp9-,,: 8?]jr]ot6J]ia9H]ukqpNkkp>]_gcnkqj`9Cn]u Se`pd9-,,Daecdp9-,,+: 8+Qoan?kjpnkh: 2. The majority of the code for this project is identical to that of the last project, so we’ll move through it a little more quickly. Once again, the variable declarations that are placed above the I]ejL]ca$% constructor in I]ejL]ca*t]ih*_o are as follows: lner]paHeop8L]npe_ha:L]npe_hao7 lner]paejpJqiL]npe_hao9-1,7 lner]paN]j`kiN]j`9jasN]j`ki$%7 3. Add the following four lines of code to the I]ejL]ca$% constructor to give the L]npe_hao Heop a length, call the ?na]paL]npe_hao$% function, and set up the ?kilhapa` event listener on the storyboard Peian before starting the Peian: L]npe_hao9jasHeop8L]npe_ha:$JqiL]npe_hao%7 ?na]paL]npe_hao$JqiL]npe_hao%7 Ikra*?kilhapa`'9jasArajpD]j`han$IkraL]npe_hao%7 Ikra*>acej$%7 4. The ?na]paL]npe_hao$% function should be added below the I]ejL]ca$% constructor. Here, the code has changed a bit, so I’ve highlighted the changed lines in bold. The particle posi- tions are now based on the center of the L]npe_haAieppan Canvas. We’ve also toned down the scaling a bit to keep the particles at a maximum of 25%. Most importantly, the last line of the function adds the particle to the L]npe_haAieppan*H]ukqpNkkp Canvas. (This is different than the I]ejL]ca H]ukqpNkkp Canvas.) 405 PARTICLE SYSTEMS lner]parke`?na]paL]npe_hao$ejpDksI]ju% w bkn$ejpe9,7e8DksI]ju7e''% w L]npe_hal]npe_ha9jasL]npe_ha$%7 ?]jr]o*OapHabp$l]npe_ha( L]npe_haAieppan*Se`pd+.)l]npe_ha*Se`pd+.%7 ?]jr]o*OapPkl$l]npe_ha( L]npe_haAieppan*Daecdp+.)l]npe_ha*Daecdp+.%7 ^upaWY_khkno9jas^upaW/Y7 N]j`*Jatp>upao$_khkno%7 ?khkn_9?khkn*Bnki=nc^$.11(_khknoW,Y(_khknoW-Y(_khknoW.Y%7 l]npe_ha*L]npe_haOd]la*Behh9jasOkhe`?khkn>nqod$_%7 l]npe_ha*Kl]_epu9N]j`*Jatp@kq^ha$%7 l]npe_ha*L]npe_haO_]ha*O_]haT9 l]npe_ha*L]npe_haO_]ha*O_]haU9N]j`*Jatp@kq^ha$%7 eb$l]npe_ha*L]npe_haO_]ha*O_]haT:*.1% l]npe_ha*L]npe_haO_]ha*O_]haT9 l]npe_ha*L]npe_haO_]ha*O_]haU9*.17 l]npe_ha*Rahk_epu*T9N]j`*Jatp$)1($ejp%1%7 l]npe_ha*Rahk_epu*U9N]j`*Jatp$)1($ejp%1%7 eb$l]npe_ha*Rahk_epu*T99,%l]npe_ha*Rahk_epu*T9.7 eb$l]npe_ha*Rahk_epu*U99,%l]npe_ha*Rahk_epu*U9.7 l]npe_ha*HebaOl]j9N]j`*Jatp$ ,%7 L]npe_hao*=``$l]npe_ha%7 L]npe_haAieppan*H]ukqpNkkp*?deh`naj*=``$l]npe_ha%7 y y 5. Add the IkraL]npe_hao$% event handler function. The code here has also been updated. The line that removes the dead particles needed to be updated to remove them from the L]npe_haAieppan object. Once again, the updated code is shown in bold. lner]parke`IkraL]npe_hao$k^fa_poaj`an(Arajp=ncoa% w bkn$ejpe9,7e8L]npe_hao*?kqjp7e''% w ?]jr]o*OapHabp$L]npe_haoWeY( ?]jr]o*CapHabp$L]npe_haoWeY%' L]npe_haoWeY*Rahk_epu*T%7 ?]jr]o*OapPkl$L]npe_haoWeY( ?]jr]o*CapPkl$L]npe_haoWeY%' L]npe_haoWeY*Rahk_epu*U%7 L]npe_haoWeY*=ca'9-7 406 CHAPTER 10 eb$L]npe_haoWeY*=ca:9L]npe_haoWeY*HebaOl]j% w L]npe_haAieppan*H]ukqpNkkp*?deh`naj*Naikra$L]npe_haoWeY%7 L]npe_hao*Naikra$L]npe_haoWeY%7 ?na]paL]npe_hao$-%7 y y Ikra*>acej$%7 y 6. Press F5 to compile and run the program. You will see something similar to Figure 10-4. The gray emitter Canvas will appear in the upper-left corner and begin emitting particles. You can use the mouse to move the emitter around the main canvas. Figure 10-4. The emitter can be dragged around the main canvas. 7. There are two things we will add to this program to improve the functionality. The first will adjust the program so that when it starts, the number of particles will increase—the program won’t begin with an initial burst of particles. Inside the I]ejL]ca$% constructor, update the ?na]paL]npe_hao$% call so that it creates only a single particle: ?na]paL]npe_hao$-%7 407 PARTICLE SYSTEMS 8. Now when the program runs, it will create only a single particle. As the program continues to run, we want to build up the number of visible particles, so inside the IkraL]npe_hao$% func- tion, add the following code as the very first line, before the bkn loop. Each time the story- board completes, another particle will be added if the number of particles on the screen is not equal to the number of particles specified. eb$L]npe_hao*?kqjp8JqiL]npe_hao%?na]paL]npe_hao$-%7 9. Press F5 to run the program. The emitter now produces one particle at a time, building up to the specified 150. Close the browser when you’re done checking out the program. 10. Let’s make one more tweak to this program. We’re going to add some gravity to pull the par- ticles downward. You’re going to be surprised how easy this is. At the top of the I]ejL]ca* t]ih*_o file, add the following variable declaration for gravity: lner]pa`kq^haCn]repu9*27 11. Inside the IkraL]npe_hao$% event handler code, just before the closing curly brace of the bkn statement, add the following line of code: L]npe_haoWeY*Rahk_epu*U'9Cn]repu7 12. Run the program again. You will see something like what is shown in Figure 10-5. Play around with the gravity setting a little bit and see what happens to the particles. If you want to play around with the spread of the particles as they are emitted, tweak the values in the line of code that sets the x velocity for each particle (l]npe_ha*Rahk_epu*T9N]j`*Jatp$)1($ejp%1%7). Figure 10-5. The particles are pulled downward by gravity. 408 CHAPTER 10 The finished version of this code is available in ParticleEmittersCompleted. I added a particle count to the top-left corner and changed the emitter Canvas to have no background color. The emitter can still be dragged around on the screen, but the application looks a little cleaner. One thing you will notice is that if you move the emitter Canvas, all of the particles move as well. If you want to be able to make trails with the particles, you’ll like the next project. Building a comet For this project, we’re going to build a comet that moves in an elliptical path, emitting particles as it travels. The particles in this project are emitted to the main canvas based on the location of the emitter. This means that as the emitter moves, the point of origin for the particles will move, but the particles will sprinkle around the main canvas, leaving a tail on the comet. 1. Open up the ParticleComet project to code along with this example. The project contains a few parts. There is the I]ejL]ca*t]ih file, which contains a black background and the Ikra Peian. We also have the Aieppan object, which in this case is an ellipse with an orange center and a translucent red edge, like the one shown in Figure 10-6. Finally, there is the L]npe_ha object, which looks just like the emitter but is smaller, as shown in Figure 10-7. Figure 10-6. The particle emitter shape used in the ParticleComet project Figure 10-7. The particle shape used in the ParticleComet project 2. Take a look at the Aieppan*t]ih*_o code-behind file. This file already has some variables declared—you should recognize them as being the necessary components for making the emitter move in an elliptical path. lq^he_`kq^ha=jcha9,7 lq^he_`kq^haOlaa`9*-7 lq^he_Lkejp?ajpan7 lq^he_LkejpN]`eqo7 3. Inside the L]npe_ha*t]ih*_o file is our usual particle-related code: lq^he_ejp=cawcap7oap7y lq^he_ejpHebaOl]jwcap7oap7y lq^he_LkejpRahk_epu7 4. Let’s start coding! Open the I]ejL]ca*t]ih*_o file. We’ll start by getting the emitter moving. Declare an instance of the Aieppan object before the I]ejL]ca$% constructor: lner]paAieppanL]npe_haAieppan9jasAieppan$%7 409 PARTICLE SYSTEMS 5. Inside the I]ejL]ca$% constructor, add the code shown in the following listing. The code will set the ?ajpan and N]`eqo values the Aieppan will use for its elliptical movement. The Aieppan is then positioned according to the cosine/sine calculations you learned about back in Chapter 6. To finish up, we set the Z-index property of the Aieppan to 1 before adding it to the H]ukqpNkkp Canvas. This will cause the particle emitter to draw on top of the particles as they are added to the H]ukqpNkkp Canvas. L]npe_haAieppan*?ajpan*T9H]ukqpNkkp*Se`pd+.) L]npe_haAieppan*Se`pd+.7 L]npe_haAieppan*?ajpan*U9H]ukqpNkkp*Daecdp+.) L]npe_haAieppan*Daecdp+.7 L]npe_haAieppan*N]`eqo*T9/,,7 L]npe_haAieppan*N]`eqo*U9-,,7 ?]jr]o*OapHabp$L]npe_haAieppan( L]npe_haAieppan*?ajpan*T' $I]pd*?ko$L]npe_haAieppan*=jcha%& L]npe_haAieppan*N]`eqo*T%%7 ?]jr]o*OapPkl$L]npe_haAieppan( L]npe_haAieppan*?ajpan*U' $I]pd*Oej$L]npe_haAieppan*=jcha%& L]npe_haAieppan*N]`eqo*U%%7 ?]jr]o*OapVEj`at$L]npe_haAieppan(-%7 H]ukqpNkkp*?deh`naj*=``$L]npe_haAieppan%7 6. Finish coding up the I]ejL]ca$% constructor with the following code. This sets an event lis- tener on the ?kilhapa` event for the Ikra storyboard before starting the storyboard. Notice that the event handler is still called IkraL]npe_hao—we’ll be augmenting the function we used before, but we’re starting with the emitter. Ikra*?kilhapa`'9jasArajpD]j`han$IkraL]npe_hao%7 Ikra*>acej$%7 7. Create the IkraL]npe_hao$% event handler as shown in the following listing. Remember that this code will run each time the Peian storyboard expires. When that happens, the code here will update the position of the Aieppan object on the main canvas, increment its =jcha, and restart the Peian. lner]parke`IkraL]npe_hao$k^fa_poaj`an(Arajp=ncoa% w ?]jr]o*OapHabp$L]npe_haAieppan( L]npe_haAieppan*?ajpan*T' $I]pd*?ko$L]npe_haAieppan*=jcha%& L]npe_haAieppan*N]`eqo*T%%7 ?]jr]o*OapPkl$L]npe_haAieppan( L]npe_haAieppan*?ajpan*U' $I]pd*Oej$L]npe_haAieppan*=jcha%& L]npe_haAieppan*N]`eqo*U%%7 L]npe_haAieppan*=jcha'9L]npe_haAieppan*Olaa`7 Ikra*>acej$%7 y 410 CHAPTER 10 8. Press F5 to compile and run the project. The comet will be drawn on the screen and will travel an elliptical path, as shown in Figure 10-8. Figure 10-8. The comet travels an elliptical path. 9. Next, we’ll add in the particles. Still working in the I]ejL]ca*t]ih*_o file, add the following declarations before the I]ejL]ca$% constructor. We’re going for a few more particles this time, and slightly less gravity, to give the particles a little more float. lner]paHeop8L]npe_ha:L]npe_hao7 lner]paejpJqiL]npe_hao9.,,7 lner]paN]j`kiN]j`9jasN]j`ki$%7 lner]pa`kq^haCn]repu9*07 10. Before the Ikra*?kilhapa` event listener inside the I]ejL]ca$% constructor, add the follow- ing two lines of code. This will initialize the Heop of particles with a length of 200 and call the ?na]paL]npe_hao$% function to create a single particle: L]npe_hao9jasHeop8L]npe_ha:$JqiL]npe_hao%7 ?na]paL]npe_hao$-%7 11. Next, code up the ?na]paL]npe_hao$% function. Once again, we’re passing an integer value to tell the function how many particles to generate. Notice that the positioning code positions the particle based on the location and size of the L]npe_haAieppan object. The Kl]_epu and O_]ha properties are randomly generated, as are the Rahk_epu and Hebaol]j. Once all that has been [...]... with this example 1 The base code for this project is very similar to the previous projects If you compile and run the project, you will see 30 particles meandering aimlessly about the canvas This was done by assigning random x and y velocities between 3 and 3 The other thing you may notice is that, in the file, two additional variables are declared The first determines the distance between two particles... 0.0010) 10–11 m3 kg–1 s–2 The easiest way to work around the gravitational constant for our particle systems is to ignore it Since we’re working with particles and not sending a manned spacecraft to Mars, the following formula will work: force = m1 m2 / distance2 Let’s check it out and see how it works Open the ParticleGravitation project This project has a bit of code in it that will place 30 instances... rather than flying off in opposite directions For this, we’ll need to add some collision detection and reaction code to our program 3 Begin by creating a new function called 4 Inside the new , as shown: function, add variables to determine the distance between two particles: 4 23 CHAPTER 10 5 Add an statement to check if two particles are colliding based on their distance: 6 Calculate the angle between the... SYSTEMS Fountains For our next particle system, we’ll take a look at how to create a fountain, like the one shown in Figure 10- 13 The particles are emitted from the top area of the tube, fly upward, and eventually fall back as they are affected by the force of gravity Figure 10- 13 A particle fountain The particle system for the fountain is similar to the one for the explosion, so rather than walk through... instead, the explosion should be allowed to happen, and then the particles will be made to flicker after a short delay To accomplish this, the property for the animation inside the storyboard was set to 3 seconds 9 Inside the function, add the following two lines of code to set a random for the storyboard, and then start it: 417 CHAPTER 10 10 Inside the function, we need to stop the storyboard before... Finally, each particle has its y velocity modified by the variable 411 CHAPTER 10 For reference, here is a listing of the completed shown previously: 412 event handler after adding the code PARTICLE SYSTEMS 13 Press F5 to compile and run the project The comet will travel the elliptical path, leaving a trail of particles behind, as shown in Figure 10-9 Figure 10-9 The comet now has a particle-based tail 14... following listing The storyboard fades the particle out over 5 seconds, and then fades it back in over the next 5 seconds The storyboard will then reverse automatically and is set to repeat endlessly 4 13 CHAPTER 10 15 Inside the function in the file, just before the line, add the following two lines of code The first line will generate a random between 5 and 10 for the storyboard, and then begin the... here—it’s the same basic particle system we’ve been using all along The particle object contains variables for velocity and mass 421 CHAPTER 10 Figure 10-15 The ParticleGravitation project randomly places 30 particles on the main canvas 1 Inside the file in the function is a loop that is used to move each particle The particles currently don’t go anywhere because they all have x and y velocities of 0 Gravity... variable to control the speed Add the following line of code to the variable declarations that precede the constructor: 2 Inside the function, add code to set the velocity of the particles being created: 3 If you’re thinking ahead, you’re figuring we’re going to be using sine and cosine to pull off the magic with this particle system, and you’re correct Still inside the function, add the following line... 424 PARTICLE SYSTEMS 11 Update the position variables: 12 Now it’s time to rotate everything back into proper position Begin by calculating the particles’ final positions prior to rotating them back: 13 Update the position of the particles on the screen Since the coordinate system was rotated about , ’s original position is added to the calculated new position 14 Finish up by rotating the velocities . SYSTEMS 9. Compile and run the program. You will see something like what is shown in Figure 10 -3. Figure 10 -3. The particles now have random color, scale, and opacity. 10. So the particle generator. particle as it is created. At 30 frames per second, that should be a maximum of 4 seconds that any given particle is on the screen. l]npe_ha*HebaOl]j9N]j`*Jatp$ ,%7 13. The IkraL]npe_hao$% event. previously: lner]parke`IkraL]npe_hao$k^fa_poaj`an(Arajp=ncoa% w eb$L]npe_hao*?kqjp8JqiL]npe_hao%?na]paL]npe_hao$-%7 bkn$ejpe9,7e8L]npe_hao*?kqjp7e''% w ?]jr]o*OapHabp$L]npe_haoWeY(?]jr]o*CapHabp$L]npe_haoWeY%' L]npe_haoWeY*Rahk_epu*T%7 ?]jr]o*OapPkl$L]npe_haoWeY(?]jr]o*CapPkl$L]npe_haoWeY%' L]npe_haoWeY*Rahk_epu*U%7 L]npe_haoWeY*=ca'9-7 eb$L]npe_haoWeY*=ca:9L]npe_haoWeY*HebaOl]j% w H]ukqpNkkp*?deh`naj*Naikra$L]npe_haoWeY%7 L]npe_hao*Naikra$L]npe_haoWeY%7 ?na]paL]npe_hao$-%7 y L]npe_haoWeY*Rahk_epu*U'9Cn]repu7 y ?]jr]o*OapHabp$L]npe_haAieppan(L]npe_haAieppan*?ajpan*T' $I]pd*?ko$L]npe_haAieppan*=jcha%& L]npe_haAieppan*N]`eqo*T%%7 ?]jr]o*OapPkl$L]npe_haAieppan(L]npe_haAieppan*?ajpan*U' $I]pd*Oej$L]npe_haAieppan*=jcha%& L]npe_haAieppan*N]`eqo*U%%7 L]npe_haAieppan*=jcha'9L]npe_haAieppan*Olaa`7 Ikra*>acej$%7 y 4 13 PARTICLE SYSTEMS 13. Press F5 to compile and run the project. The comet will travel the elliptical path,