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 } |