#!/usr/bin/python3
# ====================================================================
# test sawrooth wave
# https://en.wikipedia.org/wiki/sawtooth_wave
# ====================================================================
import math
import matplotlib.pyplot as plt
# --------------------------------------------------------------------
# ---- class - triangle wave object
# ---- t0 start (time +/- ? if random)
# ---- hz frequency (hertz) (cycles/second)
# ---- ran randomize start time
# --------------------------------------------------------------------
class sawtoothWave:
def __init__(self,t0,hz):
self.t0 = t0
self.hz = hz
# ---- return wave's size/value/magnitude/strength at
# ---- time t (seconds since t0)
def value(self,t):
freq = self.hz
period = 1/freq
v = 2*(t/period - math.floor((1/2) + (t/period)))
return v
# -------------------------------------------------------------------
# ---- 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
# --------------------------------------------------------------------
# ---- main
# --------------------------------------------------------------------
if __name__ == '__main__':
# ---- required: t0 < tstart < tend
hz = 10 # wave frequency (hertz) (cycles/second)
t0 = 0.0 # wave start time (second)
sstart = 0.0 # sample start time (second)
send = 2.0 # sample end time (second)
ssize = 1000 # sample size
print(f't0 = {t0}')
print(f'hz = {hz}')
print(f'sstart = {sstart}')
print(f'send = {send}')
print(f'ssize = {ssize}')
# ---- get a list of sample time values
tlst = time_list(sstart,send,ssize)
print(f'tlst len={len(tlst)} [0]={tlst[0]}')
# ---- get a list of value samples for each time in tlst
sawtooth_wave = sawtoothWave(t0,hz)
vlst = calculate_wave_values(tlst,sawtooth_wave)
print(f'vlst len={len(vlst)} [0]={vlst[0]}')
# ---- plot data
plt.figure(figsize=(10,5))
plt.title('Sawtooth Wave')
plt.xlabel('sample time', fontsize=14)
plt.ylabel('sample value', fontsize=14)
plt.plot(tlst,vlst,'black')
plt.grid()
plt.show()