c for loop instead of an if statement - c

distance = (u * t + (0.5 * (a * t * t)));
printf("distance is ");
printf("%0.5f\n", distance);
printf("\n");
if (distance >= height)
{
bounce = ((COR*COR)*height);
printf("The bounce is ");
printf("%0.5f\n", bounce);
bounce_height = bounce;
bounce = ((COR*COR)*bounce_height);
printf("The bounce is ");
printf("%0.5f", bounce);
break;
}
so basically I am making a program to get data values for a bouncing ball and I need to know the bounce heights which is calculated using COR (coefficient of restitution squared) * drop height. I need it to be able to loop through the program so after the first bounce height is calculated that value is then used in the equation to get the next one and so on. I am unsure on how to do this I started with an IF statement but that will only do as many calculations as i program in. Any help with this would be amazing thanks in advance. PS the values for COR and height are asked for from the user early in the program.

You should use a while loop and set a minimum heigth that stops the loop.
Something like:
#define MINIMUM_HEIGTH 0.1
float current_heigth = 2.0;
while (current_heigth > MINIMUM_HEIGTH)
{
printf("Current heigth is %f\n", current_heigth);
current_heigth = calculate_new_heigth_after_bounce...;
}
This will keep printing the heigth after each bounce until the heigth get below MINIMUM_HEIGTH

Related

Track Minimum Value of a Signal In Real Time

I'm currently tracking the analog value of a photodetector coming into my system. The signal itself is cleaned, filtered (low pass and high pass), and amplified in hardware before coming into my system. The signal has a small amount of DC walk to it, which is giving me some trouble. I've attempted to just move the min up by 1% every 50 reads of the ADC,but it adds more noise than I'd like to my signal. Here's a snapshot of what I'm pulling in below (blue = signal, max/min average = green, red = min) The spikes in the red signal can be ignored that's something I'm doing to say when a certain condition is met.
Right now my function for tracking min is this:
//Determine is value is outside max or min
if(data > max) max = data;
if(data < min) min = data;
//Reset function to bring the bounds in every 50 cycles
if(rstCntr>=50){
rstCntr=0;
max = max/1.01;
min = min*1.01;
if(min <= 1200) min = 1200;
if(max >= 1900) max = 1900;
}
That works fine except when I do that 1% correction to make sure we are still tracking the signal it throws other functions off which rely on the average value and the min value. My objective is to determine:
On the negative slope of the signal
Data coming in is less than the average
Data coming in is 5% above the minimum
It is really #3 that is driving everything else. There is enough slack in the other two that they aren't that affected.
Any suggestions for a better way to track the max and min in real-time than what I'm doing?
EDIT: Per comment by ryyker: here is additional information and reproducible example code
Need more clearly described: I'm reading an analog signal approximately once every 2ms and determining whether that signal has crossed a threshold just above the minimum value of the analog signal. The signal has some DC walk in it which doesn't allow me to simply set the lowest value seen since power-on as the minimum value.
The question: On a reading-by-reading basis, how can I track the min of a signal that doesn't have a consistent minimum value?
int main(void) {
while (1)
{
//******************************************************************************
//** Process analog sensor data, calculate HR, and trigger solenoids
//** At some point this should probably be moved to a function call in System.c,
//** but I don't want to mess with it right now since it works (Adam 11/23/2022)
//******************************************************************************
//Read Analog Data for Sensor
data = ADC1_ReadChannel(7);
//Buffer the sensor data for peak/valley detection
for(int buf=3;buf>0;buf--){
dataBuffer[buf] = dataBuffer[buf-1];
}
dataBuffer[0] = data;
//Look for a valley
//Considered a valley is the 3 most recent data points are increasing
//This helps avoid noise in the signal
uint8_t count = 0;
for(int buf=0;buf<3;buf++) {
if(dataBuffer[buf]>dataBuffer[buf+1]) count++;
}
if(count >= 3) currentSlope = true; //if the last 3 points are increasing, we just passed a valley
else currentSlope = false; //not a valley
// Track the data stream max and min to calculate a signal average
// The signal average is used to determine when we are on the bottom end of the waveform.
if(data > max) max = data;
if(data < min) min = data;
if(rstCntr>=50){ //Make sure we are tracking the signal by moving min and max in every 200 samples
rstCntr=0;
max = max/1.01;
min = min*1.01;
if(min <= 1200) min = 1200; //average*.5; //Probably finger was removed from sensor, move back up
if(max >= 1900) max = 1900; //Need to see if this really works consistently
}
rstCntr++;
average = ((uint16_t)min+(uint16_t)max)/2;
trigger = min; //Variable is only used for debug output, resetting each time around
if(data < average &&
currentSlope == false && //falling edge of signal
data <= (((average-min)*.03)+min) && //Threshold above the min
{
FireSolenoids();
}
}
return 1;
}
EDIT2:
Here is what I'm seeing using the code posted by ryyker below. The green line is what I'm using as my threshold, which works fairly well, but you can see max and min don't track the signal.
EDIT3:
Update with edited min/max code. Not seeing it ever reach the max. Might be the window size is too small (set to 40 in this image).
EDIT4:
Just for extra clarity, I'm restating my objectives once again, hopefully to make things as clear as possible. It might be helpful to provide a bit more context around what the information is used for, so I'm doing that also.
Description:
I have an analog sensor which measures a periodic signal in the range of 0.6Hz to 2Hz. The signal's periodicity is not consistent from pulsewave to pulsewave. It varies +/- 20%. The periodic signal is used to determine the timing of when a valve is opened and closed.
Objective:
The valve needs to be opened a constant number of ms after the signal peak is reached, but the time it physically takes the valve to move is much longer than this constant number. In other words, opening the valve when the peak is detected means the valve opens too late.
Similar to 1, using the valley of the signal is also not enough time for the valve to physically open.
The periodicity of the signal varies enough that it isn't possible to use the peak-to-peak time from the previous two pulsewaves to determine when to open the valve.
I need to consistently determine a point on the negative sloped portion of the pulsewave to use as the trigger for opening the valve.
Approach:
My approach is to measure the minimum and maximum of the signal and then set a threshold above the minimum which I can use to determine the time the open the valve.
My thought is that by setting some constant percentage above the minimum will get me to a consistent location on the negative sloped which can be used to open the valve.
"On a reading-by-reading basis, how can I track the min of a signal that doesn't have a consistent minimum value?"
By putting each discrete signal sample through a moving window filter, and performing statistical operations on the window as it moves, standard deviation can be extracted (following mean and variance) which can then be combined with mean to determine the minimum allowed value for each point of a particular waveform. This assumes noise contribution is known and consistent.
The following implementation is one way to consider.
in header file or top of .c
//support for stats() function
#define WND_SZ 10;
int wnd_sz = WND_SZ;
typedef struct stat_s{
double arr[10];
double min; //mean - std_dev
double max; //mean + std_dev
double mean; //running
double variance;//running
double std_dev; //running
} stat_s;
void stats(double in, stat_s *out);
in .c (edit to change max and min)
// void stats(double in, stat_s *out)
// Used to monitor a continuous stream of sensor values.
// Accepts series of measurement values from a sensor,
// Each new input value is stored in array element [i%wnd_sz]
// where wnd_sz is the width of the sample array.
// instantaneous values for max and min as well as
// moving values of mean, variance, and standard deviation
// are derived once per input
void ISL_UTIL stats(double in, stat_s *out)
{
double sum = 0, sum1 = 0;
int j = 0;
static int i = 0;
out->arr[i%wnd_sz] = in;//array index values cycle within window size
//sum all elements of moving window array
for(j = 0; j < wnd_sz; j++)
sum += out->arr[j];
//compute mean
out->mean = sum / (double)wnd_sz;
//sum squares of diff between each element and mean
for (j = 0; j < wnd_sz; j++)
sum1 += pow((out->arr[j] - out->mean), 2);
//compute variance
out->variance = sum1 / (double)wnd_sz;
//compute standard deviation
out->std_dev = sqrt(out->variance);
//EDIT here:
//mean +/- std_dev
out->max = out->mean + out->std_dev;
out->min = out->mean - out->std_dev;
//END EDIT
//prevent overflow for long running sessions.
i = (i == 1000) ? 0 : ++i;
}
int main(void)
{
stat_s s = {0};
bool running = true;
double val = 0.0;
while(running)
{
//read one sample from some sensor
val = someSensor();
stats(val, &s);
// collect instantaneous and running data from s
// into variables here
if(some exit condition) break
}
return 0;
}
Using this code with 1000 bounded pseudo random values, mean is surrounded with traces depicting mean + std_dev and mean - std_dev As std_dev becomes smaller over time, the traces converge toward the mean signal:
Note: I used the following in my test code to produce data arrays of a signal with constant amplitude added to injected noise that diminishes in amplitude over time.
void gen_data(int samples)
{
srand(clock());
int i = 0;
int plotHandle[6] = {0};
stat_s s = {0};
double arr[5][samples];
memset(arr, 0, sizeof arr);
for(i=0; i < samples; i++)//simulate ongoing sampling of sensor
{
s.arr[i%wnd_sz] = 50 + rand()%100;
if(i<.20*samples) s.arr[i%wnd_sz] = 50 + rand()%100;
else if(i<.40*samples) s.arr[i%wnd_sz] = 50 + rand()%50;
else if(i<.60*samples) s.arr[i%wnd_sz] = 50 + rand()%25;
else if(i<.80*samples) s.arr[i%wnd_sz] = 50 + rand()%12;
else s.arr[i%wnd_sz] = 50 + rand()%6;
stats(s.arr[i%wnd_sz], &s);
arr[0][i] = s.mean;
arr[1][i] = s.variance;
arr[2][i] = s.std_dev;
arr[3][i] = s.min;
arr[4][i] = s.max;
}
//
Plotting algorithms deleted for brevity.
}

How to make turret pointing at an object using 2d frames in tower defense games?

I'm working on tower defense game and I'm using stencyl.
I want to make 2d tower defense game like (clash of clans), so I want to know how to make a turret pointing at an object using frames like (canon in clash of clans).
I mean when an object enters the range of tower the tower will point at it without rotating the tower but using 2d frames instead by some way using code or mathematical way.
I've found the solution.
Do this :
float Direction = 0;
float FinalDirection = 0;
float DirectionDegree = 0;
int NumberOfDirections = 0; // eg: 24 or 32 or even 128 or anything Directions
DirectionDegree = 360 / NumberOfDirections;
void update() // this will run every frame
{
Direction = Math.atan2(target.y - tower.y, target.x - tower.x ) * (180 / Math.PI);
if(Direction < 0)
{
Direction += 360;
}
FinalDirection = Direction / DirectionDegree;
tower.frame = FinalDirection;
}

Using programming language C to model a linear chain of atomic oscillators (atoms connected by series of springs) [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
This question involves using the programming language C to model a linear chain of atomic
oscillators. I’ve included my work on this so far on the next few pages. But basically, N # of
atoms are connected in a straight line by a series of springs (I’ve drawn a picture on the next
page). The two ends can be thought of as walls. The equation of motion that governs each atom
in this chain can be derived to get the following
A(t) – k/m * [ x(i-1) – 2x(i) + x(i+1) ] = 0
Where 1 <= i < = N and the equations are coupled. Here, k is the spring force.
So, there exists a system of second order, coupled differential equations (one for each atom in
the chain).
The question is to use the programming language C to model the behavior of these atomic
oscillators.
Specifically, my teacher wants me to use Verlet integration as follows
This question involves using the programming language C to model a linear chain of atomic
oscillators. I’ve included my work on this so far on the next few pages. But basically, N # of
atoms are connected in a straight line by a series of springs (I’ve drawn a picture on the next
page). The two ends can be thought of as walls.
Here is the given data:
(1) A force is applied to the first atom in the chain that affects the rest of the atoms in the
chain
(2) Thus, there exists an initial velocity (choose an initial velocity that makes sense at the
atomic level)
(3) Choose a delta time that allows us to see the behavior of the atoms (~ 10^-14 sec).
(4) Use the Verlet integration algorithm to find the position and velocity of each atom in the
chain for a given time (essentially modeling the behavior of the atoms).
(5) *Choose a spring force that would properly model the interaction of atoms.
(6) *Let m = mass be the mass of an atom. Choose this mass.
This is all to be done using C.
Specifically, my teacher wants me to use Verlet integration as follows:
https://i.stack.imgur.com/KfDgM.jpg
https://i.stack.imgur.com/K7r5Y.jpg
https://i.stack.imgur.com/ekWO2.jpg
In a physical simulation you need to store the state for current time T and use this to compute a new state at time T + \delta T. Then repeat until T reaches the desired end time. For some very simple problems, you can get away with storing just the current state and update it on the fly. But this problem is more easily done with 2 states. Let's call them C and N for the current T and next T+\delta T states respectively. The basic algorithm is
Store initial conditions in N. For starters: N.t = 0
Emit N as output.
while (N.t < end of simulated time) {
Copy N to C
Use C to compute N // N.t = C.t + delta_t and do Verlet integration...
Emit N as output.
}
You can get fancy with pointers to avoid the copy operation. But I gather you're a new C programmer. Don't go there yet.
The states can consist of arrays to hold the positions (x coordinates) of the atoms, their velocities, and accelerations. I suggest you declare these as struct fields:
#define MAX_ATOM_COUNT (20) // or whatever, but don't make much bigger than needed
typedef struct state_s {
double t; // Time of this state
int n_atoms; // Actual number of atoms must be <= MAX_ATOM_COUNT.
double x[MAX_ATOM_COUNT]; // position
double v[MAX_ATOM_COUNT]; // velocity
double a[MAX_ATOM_COUNT]; // acceleration
} STATE;
The advantage of structs is that you can do the copy operation of the algorithm with one statement:
STATE current, next;
next.t = 0;
...
while (next.t < SIMULATION_END_TIME) {
current = next;
...
You get to do the rest.
I am new in C, I tried to follow up on your concept but I could not go past the idea. I came up with a little code but it's full of errors. Hope you can advise.
Here is the code:
#include<stdio.h>
#include<conio.h>
#include<graphics.h>
#include<math.h>
//#define MAX_ATOM_COUNT (20)
//
typedef struct state_s{
double t; // Time of this state
int n_atoms;
/* Actual number of atoms must be <=
* MAX_ATOM_COUNT
*/
double x[MAX_ATOM_COUNT]; // position
double v[MAX_ATOM_COUNT]; //velocity
double a[MAX_ATOM_COUNT]; // acceleration
}STATE;
void main()
{
/*
* Let the current initial conditions be c
* Let the next condition be n
* Let the MAX_ATOM_COUNT be user specified
*
*/
double t, MAX_ATOM_COUNT;
double SIMULATION_END_TIME;
double c, n;
int gd = DETECT, gm;
initgraph(&gd, &gm, "C:\\tc\\bgi");
//Path for graphics drivers
line(100, 200, 150, 200);
arc(200, 200, 0, 180, 50);
arc(260, 200, 0, 180, 50);
arc(230, 200, 180, 360, 20);
arc(320, 200, 0, 180, 50);
arc(290, 200, 180, 360, 20);
arc(380, 200, 0, 180, 50);
arc(350, 200, 180, 360, 20);
line(430, 200, 470, 200);
getch();
closegraph();
//Value of simulation end time
printf(" Enter the value of simulation duration\n");
scanf("%d", &SIMULATION_END_TIME);
// Store initial conditions in N
printf("Enter the Maximum atom count\n");
scanf("%d", &MAX_ATOM_COUNT);
printf("Enter the current initial conditions\n");
scanf("%d", &c);
printf("Enter the next conditions\n");
scanf("%d", &n);
while (t < SIMULATION_END_TIME) {
c = n;
n * t = c * t + delta_t;
// Do verlet Integration Computation
x1 = x0 + (x0 - x1) + a*pow(dt, 2);
printf("%d", &n);
}
STATE current, next;
next.t = 0;
while (next.t < SIMULATION_END_TIME) {
c = n;
}
printf("The position is:\n");
printf("%d", &x);
printf("The velocity is:\n");
printf("%d", &v);
printf("The acceleration is:\n");
printf("%d", &a);
}

Length of the intercept from intersection of a line with a cylinder (ring)

I have some sources with coordinates (xn, yn, zn) w.r.t a center C of a ring and unit vectors (ns_ux, ns_uy, ns_uz) along my line of sight. I want to calculate whether these sources pass through a cylinder of inner and outer radius 9.5 and 10.5 units, respectively. If they intersect this cylinder (or I call it ring, sometimes), then I would like to calculate the length of this intercept. My position is outside of this ring and there are sources which lie beyond the center C on the other side. These sources, therefore will pass through this ring twice. This picture should help visualize this problem.
#define PI 3.142
int main(){
int k,number=200;
float r_min=9.50000;
float r_max=10.500000;
float step=0.3;
float z_c = 3.0;
float ns_ux[number],ns_uy[number],ns_uz[number],xn[number], yn[number],zn[number],l[number],b[number],ns[number],x_comp,y_comp,z_comp,radial;
FILE* val= NULL;
val=fopen("novae_uniform_unitvectors.txt", "r");
for(k=0;k<=(number-1);k++){
fscanf(val,"%f %f %f %f %f %f %f %f %f", &xn[k], &yn[k], &zn[k], &ns_ux[k], &ns_uy[k], &ns_uz[k], &l[k], &b[k], &ns[k]);
float u=0.;
for (u=0.;u<=30.;u=u+step){
x_comp=xn[k]+u*ns_ux[k];
vector addition : calculating the x_comp w.r.t the center C when stepped by 'u' units along my l.o.s.
y_comp=yn[k]+u*ns_uy[k];
radial=pow((x_comp*x_comp+y_comp*y_comp),0.5);
if (radial >=r_min && radial <=r_max){
z_comp=zn[k]+u*ns_uz[k];
checking if the height is consistent with the ring's height
if(z_comp >=-z_c && z_comp <= z_c)
printf("%f\t%f\t%f\t%f\n",l[k],u, z_comp, radial);
}
}
}
return 0.;
}
This 'radial' values gives me a list of points where my line of sight intersects with the ring. But, I require only the end points to calculate the length of the intercept on the ring.
e.g. in the case listed below, my l.o.s. passes through the ring at I and then comes off at II. Then it keeps going until it hits the ring again at III and then come out of it at IV. I need to store only I, II , III and IV points in my file. How would I be able to do it ?
longitude..........u........ z_comp........radial
121.890999 0.100000 0.016025 9.561846 I
121.890999 0.200000 0.038453 9.538050
121.890999 0.300000 0.060881 9.515191 II
121.890999 4.799998 1.070159 9.518372 III
121.890999 4.899998 1.092587 9.541364
121.890999 4.999998 1.115016 9.565292
...... skipping to save space........
121.890999 7.399995 1.653297 10.400277
121.890999 7.499995 1.675725 10.444989
121.890999 7.599995 1.698153 10.490416 IV
Figured out a way to store only the final and initial values by using a boolean operator as follows (continued from the code in the question) :
define bool change = true;
...(rest of the program)...
if(radial >= r_min && radial <= r_max) {
z_comp = zn[k] + u * ns_uz[k];
if (z_comp >= -z_c && z_comp <= z_c)
if (change) {
printf("%f\t%f\t%f\t%f\t", l[k], b[k], ns[k], radial[i]);
change = !change;
}
} else { // if the condition of radial and z_comp is not met
if (!change) {
fprintf(fp, "%f\n", radial[i - 1]);
change = !change;
}
}
This would store only the first and the last values of the radial component (i.e. the end points of the intercept of the line of sight vector on the ring)

C++: Trouble with a nested if loop not ending properly

stackoverflow. I'm a newbie at C++ and I've got one last issue with my assignment. I'm trying to write a program that calculates the speed at which an object falls from a base height, and displays that information as the height of the object versus the amount of time (in seconds) that it has been falling. This is the code I have so far:
#include <stdio.h>
int main() {
int acceleration, altitude, time;
double distance;
acceleration = 32;
time = 0;
printf("What is the altitude you are dropping your object from?\n");
scanf("%d", &altitude);
printf("Time Altitude\n");
while (altitude > 0){
distance = ((0.5 * acceleration) * (time * time));
altitude = altitude - distance;
printf("%d %d\n", time, altitude);
time++;
if (altitude <= 0){
altitude = 0;
}
}
return 0;
}
I know the equation for distance is slightly off, but what I'm more concerned about at the moment is that the program does not print out an altitude of 0 when the object hits the ground. Instead, it prints out -104, and since negative distance isn't achievable, I'd like to fix this.
So my question is this: what is wrong with my while loop/ nested if loop that is causing the program to not print out 0 for the final entry in the table?
Alter the altitude before printing.
while (altitude > 0){
distance = ((0.5 * acceleration) * (time * time));
altitude = altitude - distance;
if (altitude <= 0){
altitude = 0;
}
printf("%d %d\n", time, altitude);
time++;
}
The issue that causes this is your sampling interval: you go in increments of one second, so your program calculates the fall to negative heights. You should change your code slightly:
while (altitude > 0){
distance = ((0.5 * acceleration) * (time * time));
if (altitude < distance) {
break;
}
altitude = altitude - distance;
printf("%d %d\n", time, altitude);
time++;
}
This will not print the time the object hits the ground. You should do this calculation after the loop, using the remaining altitude, speed (acceleration*time), and acceleration, and solving the equation for the time remaining, getting the fraction representing seconds.
You are printing out altitude before it gets set to 0. Since your formula assumes time happens in 1 second intervals, what gets printed out is the altitude at that time. So if you dropped an object from 20 feet, after 1 second it would be at 4 feet and after 2 at -60 feet- where it hits the ground would actually be 1.25 seconds.

Resources