Page 2 of 2

Re: Line intersection

Posted: Sun Nov 06, 2022 8:50 am
by AZJIO
I don’t understand how this can be applied, but earlier I had the task of creating a tangent to a sinusoid to show a graph of the discharge of a capacitor in a power supply, and it was necessary to create 2 tangent lines, one straight line, and the other exponential. The straight line is the discharge with a current that does not change, and the exponential is the decrease in current through the active resistance of the resistor as the voltage decreases.
From the graph it will be understood what the voltage ripples will be.
screenshot, code AutoIt

Download: yandex upload.ee

Code: Select all

; AZJIO
; https://www.purebasic.fr/english/viewtopic.php?p=590980#p590980

EnableExplicit

Declare Draw_Sinusoid(ColorGr)
Declare Draw_Graph2(ColorGr)
Declare Draw_Graph3(ColorGr)
Declare Draw_Graph31(ColorGr)
Declare Draw_Grid(ColorGr)
Declare Draw_Text(ColorGr)
Declare start()
Declare Reading()
Declare WinCallback(hWin, Msg, wParam, lParam)


;- перечисления
Enumeration
	#txt0
	#txt1
	#txt2
	#txt3
	#txt4
	#txt5
	#txt6
	#txt7
	#txt8
	#txt9
	#txtUcr
	#txtIn
	#txtkp
	#Um00
	#Rn00
	#Cf00
	#f00
	#k200
	#k300
	#R1rt00
	#R2rt00
	#ktr00
	#Cnv
	#btnStart
EndEnumeration

#Window = 0

Global.d Um, Rn, Cf, f, k2, k3, R1rt, R2rt, ktr, IN, Rtr, kp, Ucr, Ud1, Ud2, Ar
Global hGUI
Global kkk

;- GUI
hGUI = OpenWindow(#Window, 0, 0, 590, 530, "Разрядка конденсатора в выпрямительном блоке питания", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget)


StringGadget(#Um00, 5, 298, 45, 23, "12")
TextGadget(#txt0, 55, 300, 280, 19, "Пиковое напряжение без нагрузки, В.")

StringGadget(#Rn00, 5, 323, 45, 23, "9")
TextGadget(#txt1, 55, 325, 280, 19, "Сопротивление нагрузки, Ом.")

StringGadget(#Cf00, 5, 348, 45, 23, "1370")
TextGadget(#txt2, 55, 350, 280, 19, "Ёмкость конденсатора, мкФ.")

StringGadget(#f00, 5, 373, 45, 23, "100")
TextGadget(#txt3, 55, 375, 535, 19, "Частота пульсаций, Гц (100 Гц при входном переменном токе 50 Гц).")

StringGadget(#k200, 5, 398, 45, 23, "0")
TextGadget(#txt4, 55, 400, 535, 19, "Коэфф. для перемещения графика U2 вверх/вниз. (оранж, экспонента)")

StringGadget(#k300, 5, 423, 45, 23, "0")
TextGadget(#txt5, 55, 425, 535, 19, "Коэфф. для перемещения графика U3 вверх/вниз (зелён. стаб.ток).")

StringGadget(#R1rt00, 5, 448, 45, 23, "0.1")
TextGadget(#txt6, 55, 450, 510, 19, "Сопротивление первичной обмотки трансформатора, Ом.")

StringGadget(#R2rt00, 5, 473, 45, 23, "0.1")
TextGadget(#txt7, 55, 475, 510, 19, "Сопротивление вторичной обмотки трансформатора, Ом.")

StringGadget(#ktr00, 5, 498, 45, 23, "1")
TextGadget(#txt8, 55, 500, 430, 19, "Коэфф. Трансформации (повышающий, если kтр>1).")

Reading()

CompilerIf  #PB_Compiler_OS = #PB_OS_Windows
	TextGadget(#txt9, 335, 303, 1, 63 , "", $11)
CompilerEndIf
TextGadget(#txtUcr, 340, 300, 240, 17, "")
TextGadget(#txtIn, 340, 325, 240, 17, "")
TextGadget(#txtkp, 340, 350, 250, 17, "")

; Создание окна диаграммы
; $FF000000,$FFCEE3E0
CanvasGadget(#Cnv, 25, 10, 551, 275)

CompilerIf  #PB_Compiler_OS = #PB_OS_Linux
	ButtonGadget(#btnStart, 480, 494, 97, 33, "Пересчитать")
CompilerEndIf


;рисуем графики при старте
Start()

CompilerIf  #PB_Compiler_OS = #PB_OS_Windows
	SetWindowCallback(@WinCallback())
CompilerEndIf


Repeat
	Select WaitWindowEvent()
			
			CompilerIf  #PB_Compiler_OS = #PB_OS_Linux
				Case #PB_Event_Gadget
					Select EventGadget()
						Case #btnStart
							Reading()
							Start()
					EndSelect
			CompilerEndIf
				
		Case #PB_Event_CloseWindow
			CloseWindow(#Window)
			End
	EndSelect
ForEver

CompilerIf  #PB_Compiler_OS = #PB_OS_Windows
Procedure WinCallback(hWin, Msg, wParam, lParam)
	Protected nNotifyCode, nID
	nID = wParam & $FFF ; LoWord
	nNotifyCode = wParam >> 16 ; HiWord

	Select Msg
		Case #WM_COMMAND
			Select nID
				Case #Um00, #Rn00, #Cf00, #f00, #k200, #k300, #R1rt00, #R2rt00, #ktr00
					Select nNotifyCode
						Case #EN_CHANGE
							Reading()
							Start()
					EndSelect
			EndSelect
	EndSelect
	ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
CompilerEndIf

Procedure Reading() ; читаем комбобоксы, высчитываем коэф.
	Um = ValD(GetGadgetText(#Um00))
	Rn = ValD(GetGadgetText(#Rn00))
	Cf = ValD(GetGadgetText(#Cf00))
	f = ValD(GetGadgetText(#f00))
	k2 = ValD(GetGadgetText(#k200))
	k3 = ValD(GetGadgetText(#k300))
	R1rt = ValD(GetGadgetText(#R1rt00))
	R2rt = ValD(GetGadgetText(#R2rt00))
	ktr = ValD(GetGadgetText(#ktr00))
	IN = Um / Rn
	Rtr = R1rt * ktr + R2rt
	kp = 1 - Rtr / (Rtr + Rn)
	Ucr = Um / Sqr(2)
	Ud1 = (Um + k3) * kp
	Ud2 = Ud1 - (Um - 50000*Um / (f * Rn * Cf) + k3) * kp
	Ar = ASin(Ud2 / (Ud1 * 0.025 * #PI))
	kkk = 230 / Um
EndProcedure

Procedure Start()
	If StartDrawing(CanvasOutput(#Cnv))
		Box(0, 0, 501, 251, $E0E3CE) ; закрашываем фон
;----- шкала по оси XY
; _GraphGDIPlus_Set_RangeX(Graph,0,20,10,1,0)
; _GraphGDIPlus_Set_RangeY(Graph,0,Um*1.1,10,1,1)
;----------------------------------------------------------макс,     деление, ,округление
;----- сетка по оси XY
; _GraphGDIPlus_Set_GridX(Graph,1,$FF6993BE)
; _GraphGDIPlus_Set_GridY(Graph,Um*1.1/10,$FF6993BE)
; _GraphGDIPlus_Set_PenSize(Graph,1)

; цвет графиков указывается в RGB, т.е. $FF339966=$FF+RGB
		Draw_Grid($BE9369) ; сетка
		Draw_Graph3($669933) ; U3 разряд стабильным током
		Draw_Graph31($800080) ; U31 касательнаяв точке пересечения
		Draw_Graph2($0066FF) ; U2 экспонента разряда на постоянное сопротивление
		Draw_Sinusoid($FF0000) ; U1 синусоида после диодов
; установка параметров после пересчёта
		SetGadgetText(#txtUcr, "Uср.кв =" + StrF(Round(Ucr, 2)) + " B (без конденсатора)")
		SetGadgetText(#txtIn, "Начальный ток нагрузки =" + StrF(Round(IN, 2)) + " А")
		SetGadgetText(#txtkp, "Коэфф. падения напряжения =" + StrF(Round(kp, 2)) + " %")
		Box(0, 251, 501, 35, $FFFFFF) ; закрашываем фон
		Box(501, 0, 50, 270, $FFFFFF) ; закрашываем фон
		Draw_Text(0)
		
	StopDrawing()
	EndIf
EndProcedure

Procedure Draw_Text(ColorGr)
	Protected i, z
	DrawingMode(#PB_2DDrawing_Transparent)
	For i = 1 To 20
		z = i * 25
		DrawText(z - 5, 253, Str(i), ColorGr)
	Next
	For i = 1 To 9
		z = -i * 25
		DrawText(506, z + 243, StrF(i / kkk * 25.1, 1), ColorGr)
	Next
EndProcedure

; сетка
Procedure Draw_Grid(ColorGr)
	Protected i, z
	FrontColor(ColorGr)
	For i = 0 To 20
		z = i * 25
		LineXY(z, 0 , z , 250)
	Next
	For i = 0 To 10
		z = i * 25
		LineXY(0, z , 500 , z)
	Next
EndProcedure

; Синусоида, синяя
Procedure Draw_Sinusoid(ColorGr)
	Protected i, U1, Xold, Yold
	FrontColor(ColorGr)
	For i = 0 To 500; Step 10
		U1 = -Um * Abs(Cos( i * #PI / 500)) * kp * kkk + 250
		If i = 0
			Yold = U1
		EndIf
		LineXY(Xold , Yold , i , U1)
		Xold = i
		Yold = U1
	Next
EndProcedure

; экспонента, оранжевая
Procedure Draw_Graph2(ColorGr)
	Protected i, U2, tt.d, Xold, Yold
	FrontColor(ColorGr)
	For i = 0 To 500 Step 25
		tt = 2 * i / f
		U2 = -(Um * Exp( -1000 * tt / (Rn * Cf)) * kp + k2) * kkk + 250
		If i = 0
			Yold = U2
		EndIf
		LineXY(Xold , Yold , i , U2)
		Xold = i
		Yold = U2
; 		Plot(i, U2) 
	Next
EndProcedure

; стабильный ток, зелёная
Procedure Draw_Graph3(ColorGr)
	Protected i, U3, tt.d, Xold, Yold
	FrontColor(ColorGr)
	For i = 0 To 500 Step 500
		tt = 2 * i / f
		U3 = -((Um - 1000 * Um * tt / (Rn * Cf) + k3) * kp) * kkk + 250
		If i = 0
			Yold = U3
		EndIf
		LineXY(Xold , Yold , i , U3)
		Xold = i
		Yold = U3
	Next
EndProcedure

; касательная, фиолетовая
Procedure Draw_Graph31(ColorGr)
	Protected i, U31, tt.d, Xold, Yold
	FrontColor(ColorGr)
	For i = 0 To 500 Step 500
		tt = 2 * i / f
		U31 = -((Cos(Ar) - Sin(Ar) * (tt * #PI / 10 - Ar)) * Um * kp) * kkk + 250
		If i = 0
			Yold = U31
		EndIf
		LineXY(Xold , Yold , i , U31)
		Xold = i
		Yold = U31
	Next
EndProcedure

Re: Line intersection

Posted: Sun Nov 06, 2022 1:53 pm
by blueb
Thanks AZJIO,

The chart looked interesting, so I took the liberty of translating Russian to English.

I'm downloading the results, since others might be curious...

Code: Select all

; =================================================================
;     File Name:    Graphic Wave Chart.pb
;   Description:    Discharging capacitor in rectifier power supply
;        Author:    AZJIO
;          Date:    November 6, 2022
;         Forum:    https://www.purebasic.fr/english/viewtopic.php?t=43460&start=15      
;Comments:
; I had the task of creating a tangent to a sinusoid to show a graph of the discharge of a capacitor 
; in a power supply, and it was necessary to create 2 tangent lines, one straight line, and the 
; other exponential. The straight line is the discharge with a current that does not change, and 
; the exponential is the decrease in current through the active resistance of the resistor as the voltage decreases.
; From the graph it will be understood what the voltage ripples will be.
; =================================================================
EnableExplicit

Declare Draw_Graph1(ColorGr)
Declare Draw_Graph2(ColorGr)
Declare Draw_Graph3(ColorGr)
Declare Draw_Graph31(ColorGr)
Declare Draw_Grid(ColorGr)
Declare start()
Declare Reading()
Declare WinCallback(hWin, Msg, wParam, lParam)


;- enums
Enumeration
   #txt0
   #txt1
   #txt2
   #txt3
   #txt4
   #txt5
   #txt6
   #txt7
   #txt8
   #txt9
   #txtUcr
   #txtIn
   #txtkp
   #Um00
   #Rn00
   #Cf00
   #f00
   #k200
   #k300
   #R1rt00
   #R2rt00
   #ktr00
   #Cnv
EndEnumeration

#Window = 0

Global.d Um, Rn, Cf, f, k2, k3, R1rt, R2rt, ktr, IN, Rtr, kp, Ucr, Ud1, Ud2, Ar
Global hGUI

;-GUI
hGUI = OpenWindow(#Window, 0, 0, 590, 530, "Discharging capacitor in rectifier power supply", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget)

; start = ButtonGadget(0, 480, 485, 97, 33, "Recalculate")


StringGadget(#Um00, 10, 298, 40, 23, "12")
TextGadget(#txt0, 55, 300, 270, 19, "No-load peak voltage, V.")

StringGadget(#Rn00, 10, 323, 40, 23, "9")
TextGadget(#txt1, 55, 325, 270, 19, "Load resistance, Ohm.")

StringGadget(#Cf00, 10, 348, 40, 23, "1370")
TextGadget(#txt2, 55, 350, 270, 19, "Capacitor capacitance, uF.")

StringGadget(#f00, 10, 373, 40, 23, "100")
TextGadget(#txt3, 55, 375, 490, 19, "Ripple frequency, Hz (100 Hz with 50 Hz AC input).")

StringGadget(#k200, 10, 398, 40, 23, "0")
TextGadget(#txt4, 55, 400, 490, 19, "Coefficient for moving the U2 graph up/down. (orange, exponent)")

StringGadget(#k300, 10, 423, 40, 23, "0")
TextGadget(#txt5, 55, 425, 490, 19, "Coefficient for moving the U3 graph up/down (green. constant current).")

StringGadget(#R1rt00, 10, 448, 40, 23, "0.1")
TextGadget(#txt6, 55, 450, 490, 19, "Transformer primary resistance, Ohm.")

StringGadget(#R2rt00, 10, 473, 40, 23, "0.1")
TextGadget(#txt7, 55, 475, 490, 19, "Transformer secondary resistance, Ohm.")

StringGadget(#ktr00, 10, 498, 40, 23, "1")
TextGadget(#txt8, 55, 500, 490, 19, "Transformation factor (increasing if ktr>1).")

Reading()

TextGadget(#txt9, 330, 303, 1, 63 , "", $11)
TextGadget(#txtUcr, 340, 300, 240, 17, "")
TextGadget(#txtIn, 340, 325, 240, 17, "")
TextGadget(#txtkp, 340, 350, 250, 17, "")

; Creating a Chart Window
; $FF000000,$FFCEE3E0
CanvasGadget(#Cnv, 40, 10, 501, 261)

; draw graphs at startup
Start()

SetWindowCallback(@WinCallback())

Repeat
   Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
         CloseWindow(0)
         End
   EndSelect
ForEver

Procedure WinCallback(hWin, Msg, wParam, lParam)
   Protected nNotifyCode, nID
   nID = wParam & $FFF ; LoWord
   nNotifyCode = wParam >> 16 ; HiWord
   
   Select Msg
      Case #WM_COMMAND
         Select nID
            Case #Um00, #Rn00, #Cf00, #f00, #k200, #k300, #R1rt00, #R2rt00, #ktr00
               Select nNotifyCode
                  Case #EN_CHANGE
                     Reading()
                     Start()
               EndSelect
         EndSelect
   EndSelect
   ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

Procedure Reading() ; read comboboxes, calculate the coefficient.
   Um = ValD(GetGadgetText(#Um00))
   Rn = ValD(GetGadgetText(#Rn00))
   Cf = ValD(GetGadgetText(#Cf00))
   f = ValD(GetGadgetText(#f00))
   k2 = ValD(GetGadgetText(#k200))
   k3 = ValD(GetGadgetText(#k300))
   R1rt = ValD(GetGadgetText(#R1rt00))
   R2rt = ValD(GetGadgetText(#R2rt00))
   ktr = ValD(GetGadgetText(#ktr00))
   IN = Um / Rn
   Rtr = R1rt * ktr + R2rt
   kp = 1 - Rtr / (Rtr + Rn)
   Ucr = Um / Sqr(2)
   Ud1 = (Um + k3) * kp
   Ud2 = Ud1 - (Um - 50000*Um / (f * Rn * Cf) + k3) * kp
   Ar = ASin(Ud2 / (Ud1 * 0.025 * #PI))
EndProcedure

Procedure Start()
   If StartDrawing(CanvasOutput(#Cnv))
      Box(0, 0, 530, 260, $E0E3CE) ; paint over the background
                                   ;----- XY scale
                                   ; _GraphGDIPlus_Set_RangeX(Graph,0,20,10,1,0)
                                   ; _GraphGDIPlus_Set_RangeY(Graph,0,Um*1.1,10,1,1)
                                   ;------------------------------------------------- ---------max, division, ,rounding
                                   ;----- grid along the XY axis
                                   ; _GraphGDIPlus_Set_GridX(Graph,1,$FF6993BE)
                                   ; _GraphGDIPlus_Set_GridY(Graph,Um*1.1/10,$FF6993BE)
                                   ; _GraphGDIPlus_Set_PenSize(Graph,1)
      
      ; the color of the graphs is indicated in RGB, i.e. $FF339966=$FF+RGB
      Draw_Grid($BE9369) ; grid
      Draw_Graph3($669933) ; U3 steady current discharge
      Draw_Graph31($800080); U31 tangent at intersection
      Draw_Graph2($0066FF) ; U2 constant resistance discharge exponent
      Draw_Graph1($FF0000) ; U1 sinusoid after diodes
                           ; setting parameters after recalculation
      SetGadgetText(#txtUcr, "Urms =" + Str(Round(Ucr, 2)) + " B (no capacitor)")
      SetGadgetText(#txtIn, "Initial load current =" + Str(Round(IN, 2)) + "A")
      SetGadgetText(#txtkp, "Voltage drop factor =" + Str(Round(kp, 2)) + "%")
      
      StopDrawing()
   EndIf
EndProcedure

Procedure Draw_Grid(ColorGr)
Protected i, z
FrontColor(ColorGr)
For i = 0 To 20
   z = i * 25
   LineXY(z, 0 , z , 260)
Next
For i = 0 To 10
   z = i * 26
   LineXY(0, z , 500 , z)
Next
EndProcedure

; Sinusoid, blue
Procedure Draw_Graph1(ColorGr)
	Protected yy, i, U1, Xold, Yold, kkk = 20
	FrontColor(ColorGr)
	For i = 0 To 500; Step 4
		U1 = -Um * Abs(Cos( i * #PI / 500)) * kp * kkk + 260
		If i = 0
			Yold = U1
		EndIf
		LineXY(Xold , Yold , i , U1)
		Xold = i
		Yold = U1
	Next
EndProcedure

; exhibitor, orange
Procedure Draw_Graph2(ColorGr)
	Protected yy, i, U2, tt, Xold, Yold, kkk = 20
	FrontColor(ColorGr)
	For i = 0 To 500 Step 50
		tt = 2 * i / f
		U2 = -(Um * Exp( -1000 * tt / (Rn * Cf)) * kp + k2) * kkk + 260
		If i = 0
			Yold = U2
		EndIf
		LineXY(Xold , Yold , i , U2)
		Xold = i
		Yold = U2
; 		Plot(i, U2) 
	Next
EndProcedure

; stable current, green
Procedure Draw_Graph3(ColorGr)
	Protected yy, i, U3, tt, Xold, Yold, kkk = 20
	FrontColor(ColorGr)
	For i = 0 To 500 Step 250
		tt = 2 * i / f
		U3 = -((Um - 1000 * Um * tt / (Rn * Cf) + k3) * kp) * kkk + 260
		If i = 0
			Yold = U3
		EndIf
		LineXY(Xold , Yold , i , U3)
		Xold = i
		Yold = U3
	Next
EndProcedure
; tangent, purple
Procedure Draw_Graph31(ColorGr)
	Protected i, U31, tt, Xold, Yold, kkk = 20
	FrontColor(ColorGr)
	For i = 0 To 500 Step 250
		tt = 2 * i / f
		U31 = -((Cos(Ar) - Sin(Ar) * (tt * #PI / 10 - Ar)) * Um * kp) * kkk + 260
		If i = 0
			Yold = U31
		EndIf
		LineXY(Xold , Yold , i , U31)
		Xold = i
		Yold = U31
	Next
EndProcedure