Basic Univers
; Codes sur les maths


;- Voila Sigma majucule (S) et Pi majuscule (?) :

Procedure SigmaM(Limite, Indice, Exp)
  Total = 0
  For k = Indice To Limite Step 1
    Total = Total + Pow(k, Exp)
  Next k
  ProcedureReturn Total
EndProcedure

Procedure PiM(Limite, Indice, Exp)
  Total = 1
  For k = Indice To Limite Step 1
    Total = Total * Pow(k, Exp)
  Next k
  ProcedureReturn Total
EndProcedure


;- Complément trigo : Convertir des angles

#RadToDeg = 180.0 / #PI
#RadToGrd = 200.0 / #PI
#DegToRad = #PI / 180.0
#DegToGrd = 200 / 180.0
#GrdToRad = #PI / 200.0
#GrdToDeg = 180 / 200.0

Macro RadToDeg(Rad)
  (Rad) * #RadToDeg)
EndMacro

Macro RadToGrd(Rad)
  (Rad) * #RadToGrd)
EndMacro

Macro DegToRad(Deg)
  (Deg) * #DegToRad)
EndMacro

Macro DegToGrd(Deg)
  (Deg) * #DegToGrd)
EndMacro

Macro GrdToRad(Grd)
  (Grd) * #GrdToRad)
EndMacro

Macro GrdToDeg(Grd)
  (Grd) * #GrdToDeg)
EndMacro


;- Complément trigo : Sécante, Cosécante, Cotangente

Macro Sec(Angle)
  1.0 / Cos(Angle))
EndMacro

Macro Csc(Angle)
  1.0 / Sin(Angle))
EndMacro

Macro Cot(Angle)
  1.0 / Tan(Angle))
EndMacro




;- Complément trigo : Arc Tangent

Procedure.d ATan2(dy.d, dx.d)
  !FLD qword [p.v_dy]
  !FLD qword [p.v_dx]
  !FPATAN
  ProcedureReturn
EndProcedure

Procedure.d ATanFull(dy.d, dx.d)
  Protected Angle.d
 
  If dx = 0.0
    If dy > 0 : Angle = #PI / 2.0
    Else : Angle = 3.0 * #PI / 2.0
    EndIf
  ElseIf dy = 0.0
    If dx > 0 : Angle = 0.0
    Else : Angle = 2.0 * #PI
    EndIf
  Else
    !FLD    qword [p.v_dy]
    !FLD    qword [p.v_dx]
    !FPATAN
    !FSTP   qword [p.v_Angle]
  EndIf
 
  If Angle < 0.0
    Angle +(2.0 * #PI)
  EndIf
 
  ProcedureReturn Angle
EndProcedure


Goto jum_code

OpenWindow(0, 0, 0, 400, 400, "ATanFull", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)

Repeat
  If StartDrawing( WindowOutput(0) )
   
   
    Box(0, 0, 400, 400, #White)
   
    DrawingMode(#PB_2DDrawing_Outlined|#PB_2DDrawing_Transparent)
   
    Circle(200, 200, 150, #Black)
    Line(20, 200, 360, 0)
    Line(200, 20, 0, 360)
   
    DrawText(352, 200, "0")
    DrawText(184, 350, "90")
    DrawText( 22, 184, "180")
    DrawText(202,  20, "270")
    DrawText(352, 184, "360")
   
    x = WindowMouseX(0)
    y = WindowMouseY(0)
   
    If x>= 0 And y>= 0 And x<400 And y<400
     
      dx = x - 200
      dy = y - 200
     
      angle.f = RadToDeg( ATan(dy / dx) )
      DrawText(0,  0, "ATan : " + StrF(angle))
     
      angle.f = RadToDeg( ATan2(dy, dx) )
      DrawText(0, 16, "ATan2 : " + StrF(angle))
     
      angle.f = RadToDeg( ATanFull(dy, dx) )
      DrawText(0, 32, "ATanFull : " + StrF(angle))
     
      LineXY(200, 200, x, y, #Red)
    EndIf
   
    StopDrawing()
  EndIf
Until WaitWindowEvent() = #PB_Event_CloseWindow


jum_code:



;- Plus Grand Diviseur Commun et Plus Petit Multiple Commun

Procedure PGCD(a.l, b.l)
  Protected c.l
 
  If a And b
    While b
      c = a % b
      a = b
      b = c
    Wend
   
    If a < 0
      a = - a
    EndIf
  Else
    a = 0
  EndIf
 
  ProcedureReturn a
EndProcedure

Procedure LCM(a.l, b.l)
  Protected c.l
 
  If a And b
    c = a * b / PGCD(a, b)
    If c < 0
      c = - c
    EndIf
  EndIf
 
  ProcedureReturn c
EndProcedure


;- Probabilités : Factorielle, Combinaisons, Arrangements

Procedure.d Factorial(n.l)
  Protected r.d
 
  If n >= 0
    r = 1
   
    While n > 1
      r * n
    Wend
  EndIf
 
  ProcedureReturn r
EndProcedure

Procedure.d Combinations(n.l, p.l)
  Protected r.d
 
  If n >= 0 And p >= 0
   
    If n >= p
      r = 1.0
     
      If p > n / 2
        p = n - p
      EndIf
     
      While p > 0
        r * n / p
        n - 1
        p - 1
      Wend
     
      If r - Round(r, 0) > 0.5
        r + 1
      EndIf
    EndIf
   
  EndIf
 
  ProcedureReturn Round(r, 0)
EndProcedure

Procedure.d Permutations(n.l, p.l)
  Protected r.d
 
  If n >= 0 And p >= 0
   
    If n >= p
      r = 1.0
     
      p = n - p
     
      While n > p
        r * n
        n - 1
      Wend
    EndIf
   
  EndIf
 
  ProcedureReturn r
EndProcedure



;- Résolution d'un trinôme... Ça peut toujours servir.

Procedure.s trinome(a, b , c)
  d = b*b - 4*a*c
  If d < 0
    ProcedureReturn "d < 0"
  ElseIf d = 0
    ProcedureReturn Str(- b/2*a)
  Else
    ProcedureReturn Str((- b - Sqr(d))/2*a)+"|" + Str((- b + Sqr(d))/2*a)
  EndIf
EndProcedure