annotate spring.mm @ 15:d5758530a039 tip

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