/**
         * Compute and return the velocity impulsion
         * given the contact point (in global frame)
         * and collision normal direction
         */
        inline Vector2D computeImpulsion
            (const Vector2D& point, const Vector2D& dir) const
        {
            if (dir.norm() < 0.999 || dir.norm() > 1.001) {
                throw std::logic_error(
                    "UnaryConstraint not normalized dir");
            }

            //Compute velocity of collisioning point
            Vector2D centerPos = _system->evalPosition(*_body);
            Vector2D centerVel = _system->evalPositionVel(*_body);
            scalar centerAngleVel = _system->evalAngleVel(*_body);
            Vector2D vel = centerVel
                + centerAngleVel*Vector2D::normal(point - centerPos);

                //FIXME: between moving bodies?


            //Build impulse
            Vector2D impulse(0.0, 0.0);

            //Declare normal and tangent unit vector
            Vector2D n = dir;
            Vector2D t = Vector2D::normal(dir);
            //Tangent (friction) component
            if (Constraint::isFriction()) {
                impulse += -Vector2D::dot(vel, t)*t;
            }
            //Normal (response) component
            scalar e = Constraint::getRestitutionCoef();
            impulse += -(e+1.0)*Vector2D::dot(vel, n)*n;

            return impulse;
        }
Delaunay::Line::Line(const Point2D & p, const Point2D & q)
{
    Vector2D t = q - p;
    Real len = t.norm();
    _a =   t.y / len;
    _b = - t.x / len;
    _c = -(_a*p.x + _b*p.y);
}
Example #3
0
 double PathToTarget(Vector2D * targ)
 {
     bool isLeft = false;
     double ang = AngleToTarget(targ);
     if (ang > 0) isLeft = true; // else false
     
     double theta;
     
     if (isLeft)
     {
         theta = position->getZ() + PI / 2.0;
     }
     else
     {
         theta = position->getZ() - PI / 2.0;
     }
     
     Vector2D * P = new Vector2D(position->getX(), position->getY());
     Vector2D * n = new Vector2D(r * cos(theta), r * sin(theta));
     
                 // R = targ - (P + n)
     Vector2D * G = P->add(n);
     Vector2D * R = targ->extract(G);
     Vector2D * ni = n->inv();
     
     double beta = R->angleTo(n->inv());
     double beta1 = ni->anticlockAngle(R);
     if (!isLeft) beta1 *= -1;
     double e = acos(r / R->norm());
     
     if (beta1 < 0)
         beta = 2 * PI - beta;
     
     /*
     if (beta1 > 0 && !isLeft)
         beta = 2 * PI - beta;
     */
      
     double eps = beta - e;
     double L = r * eps;
     
     double Rn = R->norm();
     double T = sqrt(Rn * Rn + r * r);
     return L + T;
 }
Example #4
0
double Vector2D::scaledCross(const Vector2D &v) const
{
	double norm = this->norm();

	//if the vectors are too small, scale them to approximately 2
	// this is done because the cross product between
	if (norm < 1.0)
	{
		Vector2D v2(this);

		v2.multiply(2.0/norm);

		norm = v.norm();

		if (norm < 1.0)
		{
			Vector2D v3(v);

			v3.multiply(2.0/norm);

			return v2.cross(v3);
		}

		return v2.cross(v);
	}

	norm = v.norm();

	if (norm < 1.0)
	{
		Vector2D v3(v);

		v3.multiply(2.0/norm);

		return this->cross(v3);
	}

	return this->cross(v);
}
Example #5
0
	//Draw lines between all particles that are within a certain distance
	void drawLines(FrameWriter *writer, std::vector<DrawablePolygonPtrType> p, const double distance, const double width) {

		int nHere = _poly.size();
		int nOther = p.size();

		for (int i=0; i<nHere; i++) {
			for(int j=0; j<nOther; j++) {

				Vector2D r =_poly[i]->_pos-(p[j]->_pos);
				//cout << r.norm() << " " << distance << std::endl;
				double norm = r.norm();
				if ((norm < distance) && (norm > 1e-5))
					writer->line(_poly[i]->_pos.getX(), _poly[i]->_pos.getY(), p[j]->_pos.getX(), p[j]->_pos.getY(), width, 0,0,0);



			}
		}
	};
Example #6
0
void Cluster::predictRelativePosition(){
    if(estimatedVelocity.x == 0.0f && estimatedVelocity.y == 0.0f)  //virgin state
        estimatedVelocity = velocity;
    else{       // else estimate new velocity from acceleration...
        if(velocity.normalizedDot(estimatedVelocity) <= -20.7){
            acceleration.reset();
        }
        else{
            // calculate new relative velocity
            float angle = 0;  //calc rotation angle to align velocity vector to x-axis
            Vector2D xAxis(1,0);
            if(velocity.norm() > 0)
                angle = acos(velocity.normalizedDot(xAxis));
            if(velocity.y > 0)
                angle = 2*PI - angle;

            Vector2D forward = estimatedVelocity.rotate(angle);
            Vector2D target = velocity.rotate(angle);

            float m = target.norm()-forward.norm();
            //filter and set acceleration magnitude...
            float a = 0;
            if(target.norm() > 0)
                a = 1-target.normalizedDot(xAxis);
            if(target.y < 0)
                a = -a;
            //filter and set acceleration angle...
        }

        //estimate new position
        float angle = 0;
        Vector2D xAxis(1,0);
        if(velocity.norm() > 0)
            angle = acos(velocity.normalizedDot(xAxis));
        if(velocity.y > 0)
            angle = 2*PI - angle;
        Vector2D forward = estimatedVelocity.rotate(angle);

        float m = forward.norm() + acceleration.m * delta;
        float a = acceleration.a * delta;

        Vector2D newVelocity;
        newVelocity.x = m * cos(abs(a));
        int sgn = 0;
        if(a != 0.0f)
            sgn = a < 0 ? -1 : 1;
        newVelocity.y = m * sin(abs(a)) * sgn;

        newVelocity = newVelocity.rotate(-angle);

        // filter - synthetic velocity
        Vector2D measured;
        Vector2D predicted;
        if(measured.normalizedDot(predicted) < 0.5){
            acceleration.reset();
            estimatedVelocity = velocity;
        }

    }

    // compute new forward velocity... => jaer code: SyntheticVelocityPredictor
}