diff spring.mm @ 0:c667dfe12d47

OK. Ther real deal.
author Robert Tubb <rt300@eecs.qmul.ac.uk>
date Mon, 19 Nov 2012 13:00:42 +0000
parents
children d346ddc50f70
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spring.mm	Mon Nov 19 13:00:42 2012 +0000
@@ -0,0 +1,225 @@
+/*
+ *  spring.cpp
+ *  simplespring
+ *
+ *  Created by Robert Tubb on 02/06/2011.
+ *  Copyright 2011 __MyCompanyName__. All rights reserved.
+ *
+ */
+
+#include "spring.h"
+#include "lump.h"
+#include "globalForces.h"
+
+#include <iostream>
+#include "globalUI.h"
+extern GlobalForces globalForces;
+extern GlobalUI globalUI;
+// statics
+int Spring::numSprings = 0;
+double Spring::maxForce = 0.0;
+double Spring::minForce = 0.0;
+bool Spring::forcesOn = true;
+
+//---------------------------------------------------------------
+Spring::Spring(){
+	//cout << "constructing a default spring" << endl;
+	
+	startPoint.setCoord(0.0,0.0); // dummy values - shouldn't get used
+	endPoint.setCoord(0.0,0.0);
+	
+	springConst = 0.3; // not needed - assume it's one and use 1/c^2 for mass
+    
+	isInScanPath = false;
+	
+	startLumpPtr = 0;
+	endLumpPtr = 0;
+	restLength = 0.0;
+	myIndex = Spring::numSprings++;
+	maxForce = 0.005;
+	minForce = -0.005;
+	
+	force.x = 0.0;
+	force.y = 0.0;
+	
+	// width of a spring is proportional to how beefy it is
+	//ofSetLineWidth(springConst*2);
+	
+}
+//---------------------------------------------------------------
+Spring::Spring(double aStartx, double aStarty, double aEndx, double aEndy, double aK){
+	// hfsjsfhfshsgr
+
+
+}
+//---------------------------------------------------------------
+void Spring::attachLump(Lump * aLump){
+	// set position of spring start to mass position
+	if(startLumpPtr == 0){
+		startLumpPtr = aLump;
+		
+	}else if(endLumpPtr == 0){
+		endLumpPtr = aLump;
+		//cout << "----------------------------------------end point attached to " << endLumpPtr << endl;
+		updateEndPoints(); // now both ends attached - set the spring start and end points to the relevant lumps
+        setRestLength(); // the default length for the spring can be set
+	}else{
+		cerr << "PERROR can't attach lump to this spring cos it's already attached both ends" << endl;
+	}
+}
+Lump * Spring::getLumpOnOtherEnd(Lump * alump){
+    if (startLumpPtr == alump){
+        return endLumpPtr;
+        
+    }else if (endLumpPtr == alump){
+        return startLumpPtr;
+    }
+    cout << "getLumpOnOtherEnd: this should never happen" << endl;
+
+    return NULL;
+}
+//---------------------------------------------------------------
+void Spring::setRestLength(){
+
+	//set rest length according to what the length is now
+		TwoVector diff(startPoint.x - endPoint.x, startPoint.y - endPoint.y);
+	
+		restLength = diff.norm();	
+
+		//restLength = 0.0;
+
+}
+	
+void Spring::setRestLength(double aLength){
+	restLength = aLength;
+	
+}
+void Spring::setSpringConstant(double aK){
+    springConst = aK;
+}
+double Spring::getLength(){
+    return startPoint.distanceTo(endPoint);
+}
+//---------------------------------------------------------------
+void Spring::updateEndPoints(){
+	// tweak the end points eg: from mass move
+	if (startLumpPtr ==0 || endLumpPtr == 0){
+		cerr << "PERROR spring masses not attached!" << endl; 
+	}else{
+		startPoint = startLumpPtr->position;
+		//cout << "start pt x = " << startPoint.x << ", y = " << startPoint.y << endl;
+		endPoint = endLumpPtr->position;
+	}
+}
+//---------------------------------------------------------------
+void Spring::calculateForce(){
+
+	if(!Spring::forcesOn){
+		force.x = 0.0;
+		force.y = 0.0;
+        return;
+	}
+	// get force from the extension
+	double xe = endPoint.x - startPoint.x;
+    double ye = endPoint.y - startPoint.y;
+	double extendedLength = sqrt(xe*xe + ye*ye);
+	
+    // doing this enables us to get away with only one division etc
+    double FF = springConst*(restLength/extendedLength - 1.0);
+
+    force.x = FF*xe;
+    force.y = FF*ye;
+  
+}
+//---------------------------------------------------------------
+TwoVector Spring::getForce(Lump * aLump){ // pass in the lump that we want the force for
+    
+	// above force refers to force at END force at START negative of this...
+	if(aLump ==  startLumpPtr){
+        TwoVector rForce;
+        rForce.setCoord(-force.x, -force.y);
+        return rForce;
+	}else if(aLump == endLumpPtr ){
+        return force;
+    }
+    cout << "PERROR this lump is not attached to this spring\n";
+
+	return force;
+	
+}
+
+
+//---------------------------------------------------------------
+void Spring::draw(){
+
+	int sxpos = startPoint.x * ofGetHeight() + globalUI.borderSize; // TODO make this nicer
+	int sypos = startPoint.y * ofGetHeight();
+	//cout << "start position = " << sxpos << "," << sypos << endl;
+	int expos = endPoint.x * ofGetHeight() + globalUI.borderSize;
+	int eypos = endPoint.y*ofGetHeight();
+	//cout << "end position = " << expos << "," << eypos << endl;
+
+	if(isInScanPath){
+        ofSetLineWidth(4);
+		ofSetColor(0, 255, 0);
+	}else{
+        ofSetLineWidth(1);
+		ofSetColor(0, 0, 255);
+	}
+    
+	ofLine(sxpos, sypos, expos, eypos);
+}
+//---------------------------------------------------------------
+double Spring::getForceMag(){
+	return force.norm();
+}
+//---------------------------------------------------------------
+void Spring::addToScanPath(){
+	isInScanPath = true;
+}
+//---------------------------------------------------------------
+void Spring::removeFromScanPath(){
+	isInScanPath = false;
+}
+//---------------------------------------------------------------
+/*
+void Spring::checkStuff(){
+	cout << "checking\n";
+}
+*/
+PressureSpring::PressureSpring(){
+    cout << "constructing a pressure spring for droplet mesh\n";
+}
+
+//---------------------------------------------------------------
+TwoVector PressureSpring::getForce(Lump * aLump){ // pass in the lump that we want the force for
+    
+    // PRESSURE STUFF
+    // by convention a positive pressure allways acts to the left as looking from start to end point
+    // ie: Droplet MUST be constructed in clockwise fashion
+    // we rotate the spring vector anti clockwise pi/2 radians this gives us the force vector
+    // x = -y , y = x except damn y coordinate points downwards so handedness is reversed
+    
+    // conveniently this is proportional to length just as pressure would be
+    //cout << "pressure spring get force\n";
+    double xe = endPoint.x - startPoint.x;
+    double ye = endPoint.y - startPoint.y;    
+	// above force refers to force at END force at START negative of this...
+	if(aLump ==  startLumpPtr){
+        TwoVector rForce;
+        rForce.setCoord(-force.x, -force.y);
+        rForce.x += ye * globalForces.pressure * 0.5;
+        rForce.y -= xe * globalForces.pressure * 0.5;
+        return rForce;
+	}else if(aLump == endLumpPtr ){
+        TwoVector rForce;
+        rForce.setCoord(force.x, force.y);
+        rForce.x += ye * globalForces.pressure * 0.5;
+        rForce.y -= xe * globalForces.pressure * 0.5;
+        return rForce;
+    }
+    cout << "PERROR this lump is not attached to this spring\n";
+    
+	return force;
+	
+}
\ No newline at end of file