# Ryan Martin
# macid: abcd123
# student number: #######
# November 23, 2011
#
#
# This is a solution for Major Assignment 5 (Lab 11) on Wednesday.

class particle1D:

    def __init__(self, m, r0, v0, a0):
        self.m = float(m)
        self.r = float(r0)
        self.v = float(v0)
        self.a = float(a0)

    def getM(self):
        return self.m

    def getR(self):
        return self.r
    
    def getV(self):
        return self.v
    
    def getA(self):
        return self.a

    def update(self, delta_t):
        self.r = self.r + self.v * delta_t + 0.5 * self.a * delta_t**2
        self.v = self.v + self.a * delta_t

    def applyAirResistance(self, cA):
        self.a = -1 * (self.v / abs(self.v)) * (cA * self.v**2) / (2 * self.m)

def runAirResistanceSim(p, cycles, delta_t, cA):
    result = [p.getV()]

    for i in range(cycles):
        p.applyAirResistance(cA)
        p.update(delta_t)

        result.append(p.getV())

    return result

'''
Design Question

Due to approximating time using intervals, v will
never reach exactly zero. If v ever 'overshot' zero,
the particle will begin to travel back in the opposite 
direction. Since air resistance will pull the particle 
back to zero again, if the particle continues to 
'overshoot' zero it's position will oscillate back
and forth as v keeps changing direction.

We can add an extra argument to runAirResistanceSim that
takes in a 'radius' value, and have the function
check during every cycle whether the particle's velocity
is within that radius of zero. If so, the simulation will
stop:

for i in range(cycles):
	if abs(p.getV()) < radius:
		break
        
	p.applyAirResistance(cA)
    p.update(delta_t)

    result.append(p.getV())
'''
##Note: This format is used by our automated marking system.
##You will see that, for inputs, the class/function/method name is
##given with the corresponding inputs to that class/function/method
##listed right after it. The expected outputs are the state
##variables of the object after calling the function/method.
'''
WED = {'test1': 
       {'inputs': ['particle1D', [1, 0, 2, 0], 'update', [0.1]],
       'outputs': [testingClass(1, 0.2, 2, 0)]},
       'test2':
       {'inputs': ['particle1D', [2.5, -1.5, -1.5, 2], 'update', [0.2]],
       'outputs': [testingClass(2.5, -1.76, -1.1, 2.0)]},
       'test3':
       {'inputs': ['particle1D', [5, 0, 2, -3], 'applyAirResistance', [1]],
       'outputs': [testingClass(5, 0, 2, -0.4)]},
       'test4':
       {'inputs': ['runAirResistanceSim', [('particle1D', [10, 10, -5, 6]), 10, 0.1, 2.5]],
       'outputs': [[-5.0, -4.6875, -4.412841796875, -4.169427137821913, -3.95212560460184, -3.7568843946699717, -3.5804571402335372, -3.420211223570421, -3.2739881633974575, -3.140000682221624, -3.016755628667221]]}}
'''