#!/usr/bin/python3
# ====================================================================
# combine several sine/cosine waves and plot the results
# 0. signals start at the same time
# 1. sine and cosine are part of this code
# 2. create your own value function
# a. must be is continuous
# b. must has a "value" method
# ====================================================================
import sys
import math
import numpy as np
import matplotlib.pyplot as plt
# --------------------------------------------------------------------
# ---- t0 start (time +/- ? if random)
# --------------------------------------------------------------------
class sineWave:
def __init__(self,hz):
self.hz = hz
# ---- return wave's size/value/magnitude/strength at
# ---- time t (seconds since time 0)
def value(self,t):
# ---- no negative sample time
if t < 0.0: t = -t
# ---- number of cycles since wave start time
cyc = t * self.hz
# ---- number of degrees in a cycle at time t
deg = (cyc * 360) % 360
# ---- return degrees
rad = math.radians(deg)
return math.sin(rad)
# --------------------------------------------------------------------
# ---- class - cosine object
# ---- hz frequency (cycles per second)
# --------------------------------------------------------------------
class cosineWave:
def __init__(self,hz):
self.hz = hz
# ---- return wave's size/value/magnitude/strength at
# ---- time t (seconds since time 0.0)
def value(self,t):
# ---- no negative sample time
if t < 0.0: t = -t
# ---- number of cycles since start time (never negative)
cyc = t * self.hz
# ---- number of degrees in a cycle in a cycle at time t
deg = (cyc * 360) % 360
# ---- return degrees
rad = math.radians(deg)
return math.cos(rad)
# -------------------------------------------------------------------
# ---- float range generator (start and end inclusive)
# -------------------------------------------------------------------
def frange(start,end,steps):
step = abs((end-start)/(steps))
f = start
while True:
yield(f)
if f is not None: f += step
if f >= end: f = None
# --------------------------------------------------------------------
# ---- calculate/generate a list of values
# ----
# ---- tlst is a list of sample times within the sample
# ---- range. Every wave function should use the same tlst.
# ---- Sample times are monotonically increasing from sample
# ---- start time to sample end time (inclusive).
# --------------------------------------------------------------------
def calculate_wave_values(tlst,wave):
slst = []
for t in tlst:
s = wave.value(t)
slst.append(s)
return slst
# --------------------------------------------------------------------
# ---- create a list of sample times
# ---- based on the sample start and end time, and the sample size
# ---- Note: the time list is a monotonic increasing list
# --------------------------------------------------------------------
def time_list(sstart,send,ssize):
tlst = []
for t in frange(sstart,send,ssize):
if t is None: break # end of range?
tlst.append(t)
return tlst
# --------------------------------------------------------------------
# ---- display list
# --------------------------------------------------------------------
def display_list(lst,num = -1,title=None):
if title is not None: print(title)
i = 0
for x in lst:
if num < 0 and i < num: break
i += 1
print(f'{x:.4f}, ',end='')
print('\n')
# --------------------------------------------------------------------
# ---- main
# --------------------------------------------------------------------
if __name__ == '__main__':
outfile = 'fft_dtat_data.csv'
# ---- use the same sampling for each wave (signal)
ssize = 100 # sampling size (number of samples)
sstart = 0.0 # sampling start time (seconds)
send = 0.01 # sampling end time (seconds)
# ---- both signals start at time 0.0
sin_hz = 100 # sine (signal) frequency (hz)
cos_hz = 230 # cosine (signal) frequency (hz)
# ---- get a list of sample times
tim_lst = time_list(sstart,send,ssize)
# ---- get a list of value samples for each time in tlst
sin_wave = sineWave(sin_hz)
sin_lst = calculate_wave_values(tim_lst,sin_wave)
# ---- get a list of value samples for each time in tlst
cos_wave = cosineWave(cos_hz)
cos_lst = calculate_wave_values(tim_lst,cos_wave)
# ---- combine (add) the two lists together
combo_lst = list(np.add(sin_lst,cos_lst))
# ---- plot sum of values vs time
#plot(tim_lst,combo_lst)
plt.plot(tim_lst,sin_lst, 'r')
plt.plot(tim_lst,cos_lst, 'b')
plt.plot(tim_lst,combo_lst, 'black')
plt.xlabel('sample time', fontsize=14)
plt.ylabel('sample value', fontsize=14)
plt.grid()
plt.show()
print()