问题
I am trying to generate a set of points, which when plotted as a graph represent a sine wave of 1 cycle. The requirements are :
- a sine wave of 1 cycle
- lower limit = 29491
- upper limit = 36043
- no of points = 100
- Amplitude = 3276
- zero offset = 32767
Code :
int main()
{
ofstream outfile;
outfile.open("data.dat",ios::trunc | ios::out);
for(int i=0;i<100;i++)
{
outfile << int(3276*sin(i)+32767) << "\n";
}
outfile.close();
return 0;
}
I am generating and storing the points in a file. When these points are plotted I get the following graph.
But I only need one cycle. How can I do this?
回答1:
taking into the formula of sine wave:
y(t) = A * sin(2 * PI * f * t + shift)
where:
A = the amplitude, the peak deviation of the function from zero.
f = the ordinary frequency, the number of oscillations (cycles)
t = time
shift = phase shift
would be:
y[t] = AMPLITUDE * sin (2 * M_PI * 0.15 * t + 0) + ZERO_OFFSET;
^^^ f = 15 cycles / NUM_POINTS = 0.15 Hz
To have one full-cycle, loop from y[0:t)
where t
is the time or number of points it takes to have a full cycle (i.e. wavelength)
回答2:
It appears you need 100 samples for one cycle, so you probably need this:
...
#define _USE_MATH_DEFINES
#include <math.h>
...
#define NB_OF_SAMPLES 100
...
double angle = 0.0;
for (int i = 0; i < NB_OF_SAMPLES; i++)
{
outfile << int(3276 * sin(angle) + 32767) << "\n";
angle += (2 * M_PI) / NB_OF_SAMPLES;
}
...
Or better:
#define NB_OF_SAMPLES 100
#define OFFSET 3276
#define AMPLITUDE 32767
...
double angle = 0.0;
for (int i = 0; i < NB_OF_SAMPLES; i++)
{
outfile << int(AMPLITUDE * sin(angle) + OFFSET) << "\n";
angle += (2 * M_PI) / NB_OF_SAMPLES;
}
...
回答3:
You need to change the for loop to iterate from 0 to 2(pi). That is one cycle for the sine wave. You might also want to change the loop counter to a double instead of integer and increment by 0.1 or something instead. screenshot from WolframAlpha.com
回答4:
The maths sine function std::sin takes its argument in radians:
arg - value representing angle in radians, of a floating-point or Integral type
If you need 1 cycle and 100 points then, knowing that there are 2pi radians in one cycle, you need something like
double rads;
for(int i=1;i<=100;i++)
{
rads = 2.0*M_PI*i/100;
// your expression in terms of std::sin(rads)
}
If, on the off chance your compiler/library doesn't have M_PI out of the box, then look here for flags that should make it available.
One thing that hasn't been touched on is the exact interval that you should generate. If you need the closed interval [0,2pi] then you will need to adjust your step sizes. I've given a half-open interval (0,2pi] and @Michael Walz has given the other half-open interval [0,2pi).
回答5:
A full cycle consists of 360 degrees. samples needed is 100.
So step size is 3.6
int main()
{
ofstream outfile;
outfile.open("data.dat",ios::trunc | ios::out);
for(int i=0;i<101;i++)
{
float rads = M_PI/180;
outfile << (float)(3276*sin(3.6*i*rads)+32767) << endl;
}
outfile.close();
return 0;
}
If number of samples is 200, then step size if 360/200 = 1.8
int main()
{
ofstream outfile;
outfile.open("data.dat",ios::trunc | ios::out);
for(int i=0;i<201;i++)
{
float rads = M_PI/180;
outfile << (float)(3276*sin(1.8*i*rads)+32767) << endl;
}
outfile.close();
return 0;
}
Output:
来源:https://stackoverflow.com/questions/50366146/sine-wave-generation-in-c