annotate 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
rev   line source
rt300@0 1 /*
rt300@0 2 * spring.cpp
rt300@0 3 * simplespring
rt300@0 4 *
rt300@0 5 * Created by Robert Tubb on 02/06/2011.
rt300@0 6 * Copyright 2011 __MyCompanyName__. All rights reserved.
rt300@0 7 *
rt300@0 8 */
rt300@0 9
rt300@0 10 #include "spring.h"
rt300@0 11 #include "lump.h"
rt300@0 12 #include "globalForces.h"
rt300@0 13
rt300@0 14 #include <iostream>
rt300@0 15 #include "globalUI.h"
rt300@0 16 extern GlobalForces globalForces;
rt300@0 17 extern GlobalUI globalUI;
rt300@0 18 // statics
rt300@0 19 int Spring::numSprings = 0;
rt300@0 20 double Spring::maxForce = 0.0;
rt300@0 21 double Spring::minForce = 0.0;
rt300@0 22 bool Spring::forcesOn = true;
rt300@0 23
rt300@0 24 //---------------------------------------------------------------
rt300@0 25 Spring::Spring(){
rt300@0 26 //cout << "constructing a default spring" << endl;
rt300@0 27
rt300@0 28 startPoint.setCoord(0.0,0.0); // dummy values - shouldn't get used
rt300@0 29 endPoint.setCoord(0.0,0.0);
rt300@0 30
rt300@0 31 springConst = 0.3; // not needed - assume it's one and use 1/c^2 for mass
rt300@0 32
rt300@0 33 isInScanPath = false;
rt300@0 34
rt300@0 35 startLumpPtr = 0;
rt300@0 36 endLumpPtr = 0;
rt300@0 37 restLength = 0.0;
rt300@0 38 myIndex = Spring::numSprings++;
rt300@0 39 maxForce = 0.005;
rt300@0 40 minForce = -0.005;
rt300@0 41
rt300@0 42 force.x = 0.0;
rt300@0 43 force.y = 0.0;
rt300@0 44
rt300@0 45 // width of a spring is proportional to how beefy it is
rt300@0 46 //ofSetLineWidth(springConst*2);
rt300@0 47
rt300@0 48 }
rt300@0 49 //---------------------------------------------------------------
rt300@0 50 Spring::Spring(double aStartx, double aStarty, double aEndx, double aEndy, double aK){
rt300@0 51 // hfsjsfhfshsgr
rt300@0 52
rt300@0 53
rt300@0 54 }
rt300@0 55 //---------------------------------------------------------------
rt300@0 56 void Spring::attachLump(Lump * aLump){
rt300@0 57 // set position of spring start to mass position
rt300@0 58 if(startLumpPtr == 0){
rt300@0 59 startLumpPtr = aLump;
rt300@0 60
rt300@0 61 }else if(endLumpPtr == 0){
rt300@0 62 endLumpPtr = aLump;
rt300@0 63 //cout << "----------------------------------------end point attached to " << endLumpPtr << endl;
rt300@0 64 updateEndPoints(); // now both ends attached - set the spring start and end points to the relevant lumps
rt300@0 65 setRestLength(); // the default length for the spring can be set
rt300@0 66 }else{
rt300@0 67 cerr << "PERROR can't attach lump to this spring cos it's already attached both ends" << endl;
rt300@0 68 }
rt300@0 69 }
rt300@0 70 Lump * Spring::getLumpOnOtherEnd(Lump * alump){
rt300@0 71 if (startLumpPtr == alump){
rt300@0 72 return endLumpPtr;
rt300@0 73
rt300@0 74 }else if (endLumpPtr == alump){
rt300@0 75 return startLumpPtr;
rt300@0 76 }
rt300@0 77 cout << "getLumpOnOtherEnd: this should never happen" << endl;
rt300@0 78
rt300@0 79 return NULL;
rt300@0 80 }
rt300@0 81 //---------------------------------------------------------------
rt300@0 82 void Spring::setRestLength(){
rt300@0 83
rt300@0 84 //set rest length according to what the length is now
rt300@0 85 TwoVector diff(startPoint.x - endPoint.x, startPoint.y - endPoint.y);
rt300@0 86
rt300@0 87 restLength = diff.norm();
rt300@0 88
rt300@0 89 //restLength = 0.0;
rt300@0 90
rt300@0 91 }
rt300@0 92
rt300@0 93 void Spring::setRestLength(double aLength){
rt300@0 94 restLength = aLength;
rt300@0 95
rt300@0 96 }
rt300@0 97 void Spring::setSpringConstant(double aK){
rt300@0 98 springConst = aK;
rt300@0 99 }
rt300@0 100 double Spring::getLength(){
rt300@0 101 return startPoint.distanceTo(endPoint);
rt300@0 102 }
rt300@0 103 //---------------------------------------------------------------
rt300@0 104 void Spring::updateEndPoints(){
rt300@0 105 // tweak the end points eg: from mass move
rt300@0 106 if (startLumpPtr ==0 || endLumpPtr == 0){
rt300@0 107 cerr << "PERROR spring masses not attached!" << endl;
rt300@0 108 }else{
rt300@0 109 startPoint = startLumpPtr->position;
rt300@0 110 //cout << "start pt x = " << startPoint.x << ", y = " << startPoint.y << endl;
rt300@0 111 endPoint = endLumpPtr->position;
rt300@0 112 }
rt300@0 113 }
rt300@0 114 //---------------------------------------------------------------
rt300@0 115 void Spring::calculateForce(){
rt300@0 116
rt300@0 117 if(!Spring::forcesOn){
rt300@0 118 force.x = 0.0;
rt300@0 119 force.y = 0.0;
rt300@0 120 return;
rt300@0 121 }
rt300@0 122 // get force from the extension
rt300@0 123 double xe = endPoint.x - startPoint.x;
rt300@0 124 double ye = endPoint.y - startPoint.y;
rt300@0 125 double extendedLength = sqrt(xe*xe + ye*ye);
rt300@0 126
rt300@0 127 // doing this enables us to get away with only one division etc
rt300@0 128 double FF = springConst*(restLength/extendedLength - 1.0);
rt300@0 129
rt300@0 130 force.x = FF*xe;
rt300@0 131 force.y = FF*ye;
rt300@0 132
rt300@0 133 }
rt300@0 134 //---------------------------------------------------------------
rt300@0 135 TwoVector Spring::getForce(Lump * aLump){ // pass in the lump that we want the force for
rt300@0 136
rt300@0 137 // above force refers to force at END force at START negative of this...
rt300@0 138 if(aLump == startLumpPtr){
rt300@0 139 TwoVector rForce;
rt300@0 140 rForce.setCoord(-force.x, -force.y);
rt300@0 141 return rForce;
rt300@0 142 }else if(aLump == endLumpPtr ){
rt300@0 143 return force;
rt300@0 144 }
rt300@0 145 cout << "PERROR this lump is not attached to this spring\n";
rt300@0 146
rt300@0 147 return force;
rt300@0 148
rt300@0 149 }
rt300@0 150
rt300@0 151
rt300@0 152 //---------------------------------------------------------------
rt300@0 153 void Spring::draw(){
rt300@0 154
rt300@0 155 int sxpos = startPoint.x * ofGetHeight() + globalUI.borderSize; // TODO make this nicer
rt300@0 156 int sypos = startPoint.y * ofGetHeight();
rt300@0 157 //cout << "start position = " << sxpos << "," << sypos << endl;
rt300@0 158 int expos = endPoint.x * ofGetHeight() + globalUI.borderSize;
rt300@0 159 int eypos = endPoint.y*ofGetHeight();
rt300@0 160 //cout << "end position = " << expos << "," << eypos << endl;
rt300@0 161
rt300@0 162 if(isInScanPath){
rt300@0 163 ofSetLineWidth(4);
rt300@0 164 ofSetColor(0, 255, 0);
rt300@0 165 }else{
rt300@0 166 ofSetLineWidth(1);
rt300@0 167 ofSetColor(0, 0, 255);
rt300@0 168 }
rt300@0 169
rt300@0 170 ofLine(sxpos, sypos, expos, eypos);
rt300@0 171 }
rt300@0 172 //---------------------------------------------------------------
rt300@0 173 double Spring::getForceMag(){
rt300@0 174 return force.norm();
rt300@0 175 }
rt300@0 176 //---------------------------------------------------------------
rt300@0 177 void Spring::addToScanPath(){
rt300@0 178 isInScanPath = true;
rt300@0 179 }
rt300@0 180 //---------------------------------------------------------------
rt300@0 181 void Spring::removeFromScanPath(){
rt300@0 182 isInScanPath = false;
rt300@0 183 }
rt300@0 184 //---------------------------------------------------------------
rt300@0 185 /*
rt300@0 186 void Spring::checkStuff(){
rt300@0 187 cout << "checking\n";
rt300@0 188 }
rt300@0 189 */
rt300@0 190 PressureSpring::PressureSpring(){
rt300@0 191 cout << "constructing a pressure spring for droplet mesh\n";
rt300@0 192 }
rt300@0 193
rt300@0 194 //---------------------------------------------------------------
rt300@0 195 TwoVector PressureSpring::getForce(Lump * aLump){ // pass in the lump that we want the force for
rt300@0 196
rt300@0 197 // PRESSURE STUFF
rt300@0 198 // by convention a positive pressure allways acts to the left as looking from start to end point
rt300@0 199 // ie: Droplet MUST be constructed in clockwise fashion
rt300@0 200 // we rotate the spring vector anti clockwise pi/2 radians this gives us the force vector
rt300@0 201 // x = -y , y = x except damn y coordinate points downwards so handedness is reversed
rt300@0 202
rt300@0 203 // conveniently this is proportional to length just as pressure would be
rt300@0 204 //cout << "pressure spring get force\n";
rt300@0 205 double xe = endPoint.x - startPoint.x;
rt300@0 206 double ye = endPoint.y - startPoint.y;
rt300@0 207 // above force refers to force at END force at START negative of this...
rt300@0 208 if(aLump == startLumpPtr){
rt300@0 209 TwoVector rForce;
rt300@0 210 rForce.setCoord(-force.x, -force.y);
rt300@0 211 rForce.x += ye * globalForces.pressure * 0.5;
rt300@0 212 rForce.y -= xe * globalForces.pressure * 0.5;
rt300@0 213 return rForce;
rt300@0 214 }else if(aLump == endLumpPtr ){
rt300@0 215 TwoVector rForce;
rt300@0 216 rForce.setCoord(force.x, force.y);
rt300@0 217 rForce.x += ye * globalForces.pressure * 0.5;
rt300@0 218 rForce.y -= xe * globalForces.pressure * 0.5;
rt300@0 219 return rForce;
rt300@0 220 }
rt300@0 221 cout << "PERROR this lump is not attached to this spring\n";
rt300@0 222
rt300@0 223 return force;
rt300@0 224
rt300@0 225 }