Impact

This forum is read only and just serves as an archive. If you have any questions, please post them on github.com/phoboslab/impact

1 decade ago by riceje7

Sorry for the long post, but i wanted to be as detailed as possible

So i'm creating a plugin with a couple custom `ig.Class` instances. one is a Vector implementation: Vec2 then i have a particle class:

    Particle = ig.Class.extend({
		pos: null,
		last: null,
		init: function (pos) {
			this.pos = new Vec2().mutableSet(pos.x, pos.y);
			this.last = this.pos;
		},
		draw: function (ctx) {
			ctx.beginPath();
			ctx.arc(this.pos.x, this.pos.y, 2, 0, 2 * Math.PI);
			ctx.fillStyle = "#2dad8f";
			ctx.fill();
		}
	});

next i have this tire function inside another class:
    tire: function (origin, radius, segments, spokeStiffness, treadStiffness) {
			var stride = (2 * Math.PI) / segments;

			var composite = new Composite();

			// particles
			for (var i = 0; i < segments; i++) {
				var theta = i * stride;
				composite.particles.push(new Particle(new Vec2(origin.x + Math.cos(theta) * radius, origin.y + Math.sin(theta) * radius)));
			}
			var center = new Particle(origin);
			composite.particles.push(center);
			// constraints
			for (i = 0; i < segments; i++) {
				composite.constraints.push(new DistanceConstraint(composite.particles[i], composite.particles[(i + 1) % segments], treadStiffness));
				composite.constraints.push(new DistanceConstraint(composite.particles[i], center, spokeStiffness))
				composite.constraints.push(new DistanceConstraint(composite.particles[i], composite.particles[(i + 5) % segments], treadStiffness));
			}

			this.composites.push(composite);
			return composite;
		}

and finally this update function inside the same class as the tire function:

    update: function (step) {
			for (var c in this.composites) {
				for (var i in this.composites[c].particles) {
					var particles = this.composites[c].particles;
					// calculate velocity
					var velocity = particles[i].pos.sub(particles[i].last).scale(this.friction);

					// ground friction
					if (particles[i].pos.y >= this.height - 1 && velocity.length2() > 0.000001) {
						var m = velocity.length();
						velocity.x /= m;
						velocity.y /= m;
						velocity.mutableScale(m * this.groundFriction);
					}

					// save last good state
					particles[i].last.mutableSet(particles[i].pos);

					// gravity
					particles[i].pos.mutableAdd(this.gravity);

					// inertia	
					particles[i].pos.mutableAdd(velocity);
				}
			}
			// relax
			var stepCoef = 1 / step;
			for (var c in this.composites) {
				var constraints = this.composites[c].constraints;
				for (var i = 0; i < step; ++i) {
					for (var j in constraints) {
						constraints[j].relax(stepCoef);
					}
				}
			}

			// bounds checking
			for (var c in this.composites) {
				var particles = this.composites[c].particles;
				for (var i in particles) {
					this.bounds(particles[i]);
				}
			}
		}

the error i am getting is at this line in the update function: `var velocity = particles[i].pos.sub(particles[i].last).scale(this.friction);` specifically the error is saying that it cannot call method `sub` of undefined. i changed the tire method above to look like this so i could debug it:

    tire: function (origin, radius, segments, spokeStiffness, treadStiffness) {
			var stride = (2 * Math.PI) / segments;

			var composite = new Composite();

			// particles
			for (var i = 0; i < segments; i++) {
				var theta = i * stride;
				var x = origin.x + Math.cos(theta) * radius;
				var y = origin.y + Math.sin(theta) * radius;
				var pos = new Vec2(x, y);
				console.log(pos);
				var particle = new Particle(pos);
				composite.particles.push(particle);
			}
			var center = new Particle(origin);
			composite.particles.push(center);
			// constraints
			for (i = 0; i < segments; i++) {
				composite.constraints.push(new DistanceConstraint(composite.particles[i], composite.particles[(i + 1) % segments], treadStiffness));
				composite.constraints.push(new DistanceConstraint(composite.particles[i], center, spokeStiffness))
				composite.constraints.push(new DistanceConstraint(composite.particles[i], composite.particles[(i + 5) % segments], treadStiffness));
			}

			this.composites.push(composite);
			return composite;
		}

when i log the `pos` variable i get the proper values being output to the console, however if still get the error. the only thing i can think is that somewhere between where the `pos` variable is created in the `tire` method and when it is passed and assigned in the `Particle` constructor it losses its value and results in the particle having a `pos.x / pos.y` value of NaN which i can see when i log the var `particles` above the error line (`var velocity = particles[i].pos.sub(particles[i].last).scale(this.friction);`). I really have no idea whats going wrong i've tried changing the `Particle` constructor's assignment of the parameter `pos` to assign it multiple ways (through the `Vec2.mutableSet()` method and setting directly. but no matter what I do it still results in a NaN value for the particle.

Can anyone see something that i am not? thanks

1 decade ago by vincentpiel

This issue is way too complex for some else than you to debug.
Just two things :

1) break down the complexity by assigning variables :
    var currPart  = particles[i]    ;
    var currPos  = currPart.pos ;
    var lastPos  = currPart.last ;

you will gain in readability, maintenability and speed.
    var velocity = particles[i].pos.sub(particles[i].last).scale(this.friction);
         // is now ...
    var velocity = currPos.sub(lastPos).scale(this.friction);

you might also break down compexity by using functions, like :
    for (var c in this.composites) {
          var compositeParticles = this.composites[c].particles;    
           for (var pIndex in compositeParticles) { 
                  this.someClearName(compositeParticles[pIndex])
           }
     }                            

2) do not debug with console.log, but rather use, for instance, the debugger of Chrome (in the Source tab) that lets you watch values just by hovering over them.
set breakpoints at the right places and hopefully you'll quickly find out.

3) last word : if composites and particles are array, you'll have a huge boost by using indexed for loop ( =0 ; <..: ++ )


i just made a particle engine, so the 'particle' word made me curious : what is the purpose of this code ?
Page 1 of 1
« first « previous next › last »