<Task>
We track the sun from the point O of latitude ฟ.
|
We assume that the earth is a sphere and forms a circlular trajectory around the sun. From geometry the movement of P is solved in terms of two-dimensional matrix for day d and hour jr with d=1..365 and jr=0..Nphis-1. Actually the graph of ี-ำ has already been obtained in suntracker1.html (in Japanese, Modula-2). Here we adopt Python to obtain similar results. |
|
P(ี, ำ) at North Latitude 35 | ||
Every 30 days |
Every day | |
Python
|
Modula-2
| |
<Python (Object Oriented Programming)>
ี and ำ are calculated at red code. [Main] sunTrackerEx.py import matplotlib.pyplot as plt import numpy as np import STglobalEx as STg def STpsiphi(id, jr, Omegad0, alphad, deltad, Nphis): ...... class getPsiPhi: def __init__(self,istep,daysyr,Omegad0,alphad,deltad,Nphis): Nis = daysyr // istep + 1 if Nphis==0: Nphis = 12 alpha = alphad*np.pi/180.0 delta = deltad*np.pi/180.0 DThetad = 360.0/float(Nphis) DTheta = DThetad*np.pi/180.0 i = 0 ii = 0 psida = np.arange(Nis) psidb = np.arange(Nis) psi2 = np.zeros((Nis, Nphis)) phi2 = np.zeros((Nis, Nphis)) while(True): phdprev = -1.0 for j in range(Nphis): ps, ph, psd, phd, Om, Omd = STpsiphi(i,j,Omegad0,alphad,deltad,Nphis) if ii<Nis: psi2[ii,j] = psd phi2[ii,j] = phd if phd*phdprev < 0.0: if phd > 0.0: psida[ii] = psd else: psidb[ii] = psd phdprev = phd ii += 1 if (i + istep) >= daysyr: break else: i += istep if Omd>1. : Omd -= 360.0 self.Omegad = Omd self.Nis = Nis self.psida = psida self.psidb = psidb self.psi2 = psi2 self.phi2 = phi2 def plotPsiPhi(): ...... w = getPsiPhi(daystep, daysyr, Omegad0, alphad, deltad, Nphis) psi2 = w.psi2 phi2 = w.phi2 Nis = w.Nis plotPsiPhi() |
<Modula-2 (Structured Programming)>
ี and ำ are calculated at red code. [MAIN] SunTracker.MOD [DEFINITION MODULE STglobal]MODULE SunTracker ฅฅฅฅฅฅ RotationParams(mode); i:= 0; (* for day number, INC = iskip or istep*) ii:= 0; (* for arrays, INC = 1 *) LOOP (* to scan days *) phidprev:= -1.0; FOR j:= 0 TO Nphis DO (* Dtheta = 360/Nphis *) STpsiphi(psid,phid,psi,phi,i,j,delta,alpha,DTheta); phione[j]:= phid; psione[j]:= psid; phi2[ii,j]:= phid; psi2[ii,j]:= psid; phidprev:= phid; END; (* of FOR j:=0 TO Nphis-1 *) IF (i MOD imon = 0) THEN IF toPlt3D THEN ChooseDataSequence(psione,phione,ndata,ii); (* psione and phione redefined *) Make3Ddata(psione,phione,ndata,u,v,w); ReverseArray(v,ndata); ReverseArray(w,ndata); One3Dplot(v,w,ndata,uu,vv,njj,0); (* Draw uu & vv in black, v & w in color *) END; END; (* of IF (i MOD imon = 0) *) INC(ii); (* next dataset *) IF isLeap AND(istep=2) AND (daysyr-1>i)AND((daysyr-i)<=istep) THEN i:= daysyr-1; (* daysyr = 365 or 366 *) ELSIF (i+istep)>=daysyr THEN EXIT; ELSE INC(i,istep); END; END; (* of LOOP, same as WHILE (i<=365) *) [DEFINITION MODULE STapplications]VAR psi2,phi2,time2: ARRAY[0..Ahigh] OF ARRAY[0..Angles] OF LONGREAL; PROCEDURE MakeRotx(VAR xmatrix: ARRAY OF LongVector; phi: LONGREAL); PROCEDURE RotVector(VAR v: LongVector; R: ARRAY OF LongVector); PROCEDURE VectorProduct(VAR C: LongVector; A, B: LongVector); PROCEDURE ScalarProduct(A, B: LongVector): LONGREAL; PROCEDURE STpsiphi(VAR psid: LONGREAL; VAR phid: LONGREAL; VAR psi: LONGREAL; VAR phi: LONGREAL; id: INTEGER; (* days 0..365 *) jr: INTEGER; (* earth's rotation *) delta: LONGREAL; (* inclination angle*) alpha: LONGREAL; (* latitude *) DTheta: LONGREAL); (* angle step *) |