package clothSimulator;

import javax.vecmath.Point2d;
import javax.vecmath.Point3d;
import javax.vecmath.Vector2d;
import javax.vecmath.Vector3d;

/**
 * Spring class for 599 assignment 1
 * @author kry
 */
public class Spring {

    Particle p1 = null;
    Particle p2 = null;
    
    /**
     * All springs share the same stiffness coefficient
     */
    static double k = 1;
    /**
     * All springs share the same camping coefficient
     */
    static double b = 1;
    
    /**
     * Rest length
     */
    double l0 = 0;
    
    /**
     * Creates a spring connecting two particles.
     * The rest length should be set
     * @param p1
     * @param p2
     */
    public Spring( Particle p1, Particle p2 ) {
        this.p1 = p1;
        this.p2 = p2;
        computeRestLength();
        p1.springs.add(this);
        p2.springs.add(this);
    }
    
    /**
     * Computes the rest length of the connected particles
     */
    public void computeRestLength() {
        l0 = p1.p0.distance( p2.p0 );
    }
    
    /**
     * Applies spring forces to the two particles
     */
    public void apply() {
        // TODO need to add forces to the particles
 
    	//here we add the spring force and the spring damping force to each of two particles
    	
    	this.p1.f.add(compSpringForce2(this.p1.p,this.p2.p));
    	this.p2.f.add(compSpringForce2(this.p2.p,this.p1.p));
    	this.p1.f.add(compDampForce2(this.p1.v,this.p2.v,this.p1.p,this.p2.p));
    	this.p2.f.add(compDampForce2(this.p2.v,this.p1.v,this.p2.p,this.p1.p));

    	
    }
    
    
    //here is a new function which computes spring forces given the positions of two particles
    //connected by a spring
    public Vector3d compSpringForce2(Point3d p1, Point3d p2){
       	Vector3d fp1= new Vector3d();
    	Vector3d p1_p2 = new Vector3d();
    	p1_p2.scaleAdd(-1, p2,p1);
    	double lngth=p1_p2.length();
    	fp1=(Vector3d)p1_p2.clone();
    	fp1.scale(-k);
    	fp1.scale(1-(l0/(lngth)));
    	return 	fp1;
    }
    
    
    Vector3d tempVel;
    //here is a function that computes the spring damping force acting on a particle moving at velocity
    //v1 with respect to another particle moving at velocity v2.  We need to find the component of the relative velocity
    //which is parallel to the vector pointing in the direction of the spring.
    public Vector3d compDampForce2(Vector3d v1, Vector3d v2, Point3d p1,Point3d p2){
    	Vector3d deltaX= new Vector3d();
    	tempVel=new Vector3d();
    	tempVel.scaleAdd(-1, v2, v1);
    	deltaX.scaleAdd(-1,p2,p1);
    	deltaX.normalize();
    	double radVelMag=tempVel.dot(deltaX);
    	Vector3d dmpForce= new Vector3d();
    	dmpForce.set(deltaX);
    	dmpForce.scale(-b*radVelMag);
    	return dmpForce;
    }
    
    
    
    //here is a function that computes a spring force on particle p1 given the other particle, p2
    //at the other end of the spring.
    public Vector2d compSpringForce(Particle p1, Particle p2){
       	Vector2d fp1= new Vector2d();
    	Vector2d p1_p2 = new Vector2d();
    	p1_p2.set(p2.p.x,p2.p.y);
    	p1_p2.scale(-1);
    	p1_p2.x=p1_p2.x+p1.p.x;
    	p1_p2.y=p1_p2.y+p1.p.y;
    	double lngth=p1_p2.length();
    	fp1=(Vector2d)p1_p2.clone();
    	fp1.scale(-k);
    	fp1.scale(1-(l0/(lngth)));
    	return 	fp1;
    }
    //here is a function that computes spring damping force on particle p1 which is attached to particle p2
    
    public Vector2d compDampForce(Particle p1, Particle p2){
    	Vector2d dmpForce= new Vector2d();
    	dmpForce.set(p1.v.x-p2.v.x, p1.v.y-p2.v.y);
    	dmpForce.scale(-b);
    	
    	return dmpForce;
    }
    
}


