I need help understanding how the pre() function in this Time class works.
Edit: I think maybe I have it, does this seem sound? So far it seems to be working.
The thing I don’t like about this is that I made it work by just dividing milli / 100
and then setting the value of milli %= 100
. It does get the tenths, but then milli
is no longer truly the value of milliseconds, so when I use this in my Time class, anywhere where milli
is used, such as getting angles for smooth clock hand rotations, it’s no longer correct.
Where I am really stuck is how to add the ability to get 1/10sec in-line with this code without affecting the value of milli
from one loop to the next.
I’ve updated the code with comments about my understanding of how this works, and which parts I don’t understand.
int lastT, deltaT, carry, milli, hundredths, tenths, sec, min, hr;
String carry100msStr, carry10msStr, carry60secStr, carry60minStr;
void setup() {
size(400, 600);
lastT = millis();
milli = 0;
hundredths = 0;
tenths = 0;
sec = second();
min = minute();
hr = hour();
}
void draw() {
background(127);
int rightNow = millis();
deltaT = rightNow - lastT;
lastT = rightNow;
milli += deltaT; // get the baseUnit count i.e. "milli"
carry = 0;
// the baseUnit can be as high as 1000
// the next unit is tenths, and we need just 100 baseUnits for one "tenth"
// divide the baseUnit count by how many you need for the next unit: floor(milli / 100)
// if there is not enough yet, this will be '0'
// if there are enough baseUnits so far, carry 1
carry = floor(milli / 100);
// not sure how to describe this
// but I see if I don't use "milli %= 1000" then milli will not count properly on the next loop
// and if I do use "milli %= 1000" then it also fails but I don't know why.
milli %= 1000;
// add "1" or "0" to the next unit, "tenths"
tenths += carry;
// need 10 of these before incrementing the next unit, "sec"
carry = floor(tenths / 10);
// not sure how to describe this
tenths %= 10;
// add "1" or "0" to the next unit, "sec"
sec += carry;
// need 60 of these before incrementing the next unit, "min"
carry = floor(sec / 60);
// not sure how to describe this
sec %= 60;
// add "1" or "0" to the next unit, "min"
min += carry;
// need 60 of these before incrementing the next unit, "hr"
carry = floor(min / 60);
// not sure how to describe this
min %= 60;
// add "1" or "0" to the next unit, "hr"
hr += carry;
// not sure how to describe this
hr %= 24;
String milliStr = nf(milli, 2) + " milli";
String tenthsStr = nf(tenths, 1) + " tenths";
String secStr = nf(sec, 2) + " seconds";
String minStr = nf(min, 2) + " minutes";
String hrStr = nf(hr, 2) + " hr";
String[] list = {
milliStr,
tenthsStr,
secStr,
minStr,
hrStr
};
showTextArrayLeft(list);
}
void showTextArrayLeft(String[] strings) {
float textH = 18;
//textFont(mono);
textSize(textH);
textAlign(LEFT, TOP);
fill(0);
for (int i=0; i<strings.length; i++) {
text(strings[i], 5, 5 + i * textH);
}
}
Previous question
I feel like I can follow the logic and it makes sense, but I have been trying to interpolate a way to include a value for tenths of a second in line with the existing logic and I just don’t understand why it’s not working, so I guess I have to admit I do t really understand why it works.
Could someone please comment on the class pre() function and show me how I would add an extra step to get the tenths of a second in between milli and second, and tell me why my attempt is not working? I would really appreciate it.
In this sketch I’m not actually using the Time class, I pulled out the parts to just work in the draw() loop.
Previous code
int lastT, deltaT, carry, milli, tenths, sec;
void setup() {
size(400, 600);
lastT = millis();
milli = 0;
tenths = 0;
sec = second();
}
void draw() {
background(127);
int rightNow = millis();
deltaT = rightNow - lastT;
lastT = rightNow;
milli += deltaT;
carry = 0;
tenths = floor(milli / 100);
String tenthsStr1 = nf(tenths, 1);
carry = floor(tenths / 10);
String carryStr = nf(carry, 1);
tenths %= 10;
String tenthsStr2 = nf(tenths, 1);
sec += carry;
sec %= 60;
String secStr = nf(sec, 2);
String[] list = {
tenthsStr1,
tenthsStr2,
carryStr,
secStr
};
showTextArrayLeft(list);
}
void showTextArrayLeft(String[] strings) {
float textH = 18;
//textFont(mono);
textSize(textH);
textAlign(LEFT, TOP);
fill(0);
for (int i=0; i<strings.length; i++) {
text(strings[i], 5, 5 + i * textH);
}
}
public class Time {
private int lastT;
private int deltaT;
private int hour, minute, second, tenth, milli;
private final float ANGLE_OFFSET = - PI /2;
private final float ANGLE_HOUR = TWO_PI / 12;
private final float ANGLE_MINUTE = TWO_PI / 60;
private final float ANGLE_SECOND = TWO_PI / 60;
Time(int h, int m, int s) {
hour = h;
minute = m;
second = s;
tenth = 0;
milli = 0;
lastT = millis();
deltaT = 0;
}
public void pre() {
// Get the elapsed time since the last draw method
int carry = 0;
int now = millis();
deltaT = now - lastT;
lastT = now;
milli += deltaT;
carry = floor(milli / 1000); // integer division
milli %= 1000;
tenth = floor(milli / 100);
second += carry;
carry = floor(second / 60); // integer division
second %= 60;
minute += carry;
carry = floor(minute / 60); // integer division
minute %= 60;
hour += carry;
hour %= 24;
}
int getHour() {
return hour;
}
float getHourHandAngle() {
float t = (hour % 12) + (minute / 60f) + (second / 3600f) + (milli/ 3600000f);
return t * ANGLE_HOUR + ANGLE_OFFSET;
}
int getMinute() {
return minute;
}
float getMinuteHandAngle() {
float t = minute + (second / 60f) + (milli / 60000f);
return t * ANGLE_MINUTE + ANGLE_OFFSET;
}
int getSecond() {
return second;
}
float getSecondHandAngle() {
float t = second + (milli / 1000f);
return t * ANGLE_SECOND + ANGLE_OFFSET;
}
int getTenth() {
return tenth;
}
int getMilli() {
return milli;
}
public String toString() {
return getHour() + ":" + getMinute() + ":" + getSecond() + "." + milli;
}
}