Reputation: 2102
The entirety of my code is a bit too much to post on to here so I'll try to show the essentials.
I am coding a simple graphically represented analogue clock (12-hour with three hands). Currently my code works if I let the clock run from default i.e. all hands start at 12. However I have added a feature that allows editing of the time shown and inherent to this, regardless of starting position of the hand, when it hits 12, the larger respective hand should then tick once. My code is below.
for (psi = 0; psi<6.28318530718-0.5236; psi+=0.5235987756) {
float xply = sin(psi);
float yply = cos(psi);
int hhx = x0 + (circleRad-100)*xply;
int hhy = y0 - (circleRad-100)*yply;
float phi;
for (phi = 0; phi<6.28318530718-0.10472; phi+=0.1047197551) {
float Multx = sin(phi);
float Multy = cos(phi);
int mhx = x0 + (circleRad-50)*Multx;
int mhy = y0 - (circleRad-50)*Multy;
float theta;
for (theta= 0; theta<6.28318530718-0.104720; theta+=0.1047197551) {
// If seconds are given then the if condition is tested
if (secPhase > 0) {
float angle = theta+secPhase;
// If second hand reach top, for loop breaks and enters a new loop for next minute, secphase is erased as new minute start from 0 secs.
if (angle > 6.28318530718-0.104720) {
plotHands(angle, x0, y0, circleRad, a, mhx, mhy, hhx, hhy, bytes);
capture.replaceOverlay(true, (const unsigned char*)a);
sleep(1);
secPhase = 0;
break;
}
// if second hand has not reached top yet, then plotting continues
plotHands(angle, x0, y0, circleRad, a, mhx, mhy, hhx, hhy, bytes);
capture.replaceOverlay(true, (const unsigned char*)a);
sleep(1);
}
// if there were no seconds given, plotting begins at 12.
else {
plotHands(theta, x0, y0, circleRad, a, mhx, mhy, hhx, hhy, bytes);
capture.replaceOverlay(true, (const unsigned char*)a);
sleep(1);
}
}
}
}
Currently my code works for seconds. There are declared and defined values, that I have not included here, that I can alter that will change the starting position of each hand and wherever the second hand is, when it hits 12 the minute hand will tick once.
This is the problem. Logically, I could just apply the same concept that I used for the second hand but migrate it to the minute hand and change the respective variable names involved so that when the minute hand does strike 12, the hour hand will move. This is the code that breaks:
for (phi = 0; phi<6.28318530718-0.10472; phi+=0.1047197551) {
if (minPhase > 0) {
float minAngle = phi + minPhase;
if (minAngle > 6.28318530718-0.10472) {
minPhase = 0;
break;
}
float Multx = sin(minAngle);
float Multy = cos(minAngle);
int mhx = x0 + (circleRad-50)*Multx;
int mhy = y0 - (circleRad-50)*Multy;
}
else {
float Multx = sin(phi);
float Multy = cos(phi);
int mhx = x0 + (circleRad-50)*Multx;
int mhy = y0 - (circleRad-50)*Multy;
}
}
I have taken only the middle for loop involving the minute hand. These loops and statements ensure that if there is no given starting point of the minute hand, the else statement will run, but if there is a starting point, the starting point will tick until it strikes twelve and which point it breaks to the hour for loop, ticks once, whilst clearing the starting point of the minute hand to start afresh in the new hour.
However once I attempt to compile the code, the compiler tells me:
error: 'mhx' was not declared in this scope
error: 'mhy' was not declared in this scope
it shows this everytime this variable is called in the function to draw the minute hands and is as if these variables have simply disappeared. They have clearly been declared and defined in my code by when attempted to be called in the for loop below it, it claims that these variables are missing.
I found also that if I removed the 'else' statement, the code compiled and run, but was broken, i.e. the minute hand was not in its supposed position.
Can anyone enlighten me please? I am still very new to C and C++.
Thank you in advance.
Upvotes: 0
Views: 411
Reputation: 15916
The variables go out of scope when they hit the closing brace of either the if or the else. Declare them outside of the scope and assign their values inside the if/else blocks.
for (phi = 0; phi<6.28318530718-0.10472; phi+=0.1047197551) {
if (minPhase > 0) {
float minAngle = phi + minPhase;
if (minAngle > 6.28318530718-0.10472) {
minPhase = 0;
break;
}
float Multx = sin(minAngle);
float Multy = cos(minAngle);
int mhx = x0 + (circleRad-50)*Multx;
int mhy = y0 - (circleRad-50)*Multy;
// Multx, Multy, mhx, mhy will go out of scope when the following brace is reached
}
else {
float Multx = sin(phi);
float Multy = cos(phi);
int mhx = x0 + (circleRad-50)*Multx;
int mhy = y0 - (circleRad-50)*Multy;
// Multx, Multy, mhx, mhy will go out of scope when the following brace is reached
}
}
You should instead do this:
for (phi = 0; phi<6.28318530718-0.10472; phi+=0.1047197551) {
float Multyx, Multy;
int mhx, mhy;
// These variables will now be visible in the entire for loop's scope not just the if or else statement they were declared into.
if (minPhase > 0) {
float minAngle = phi + minPhase;
if (minAngle > 6.28318530718-0.10472) {
minPhase = 0;
break;
}
Multx = sin(minAngle);
Multy = cos(minAngle);
mhx = x0 + (circleRad-50)*Multx;
mhy = y0 - (circleRad-50)*Multy;
}
else {
Multx = sin(phi);
Multy = cos(phi);
mhx = x0 + (circleRad-50)*Multx;
mhy = y0 - (circleRad-50)*Multy;
}
}
Upvotes: 3
Reputation: 17956
You need to move mhx
and mhy
to the scope above the if
statement to be visible outside the if/else.
for (phi = 0; phi<6.28318530718-0.10472; phi+=0.1047197551) {
int mhx, mhy; // move declaration here
if (minPhase > 0) {
float minAngle = phi + minPhase;
if (minAngle > 6.28318530718-0.10472) {
minPhase = 0;
break;
}
float Multx = sin(minAngle);
float Multy = cos(minAngle);
mhx = x0 + (circleRad-50)*Multx; // no longer a declaration, just assignment
mhy = y0 - (circleRad-50)*Multy;
}
else {
float Multx = sin(phi);
float Multy = cos(phi);
mhx = x0 + (circleRad-50)*Multx; // no longer a declaration, just assignment
mhy = y0 - (circleRad-50)*Multy;
}
}
I assume you have other code in the body of your for
loop after this if
statement that you haven't shown.
Upvotes: 0