Sayın tyuksel, kusura bakmazsan bir gönderim daha olacak, biraz yer kaplayan..
Bir blog açmıştım, oradaydı gönderilerim.. artık kullanamıyorum o blogu maalesef.
Direk Excel ile ilgili olmasa da kodlar Excel VBA içerisine adapte edilebilir.
VB6 için Bezier Eğrileri çizdirmeye yönelik bir uygulama..
Bezier Polinom formunda bir çalışma..
Exe dosya buradan .. http://www.mediafire.com/file/xtji4z...zierCurves.exe
Module içi Public tanımlamalar..
Faktöriyel hesabı yapan fonksiyonKod:Option Explicit Public Type POINT_DEFINION X As Double Y As Double End Type Public ControlPointsArray() As POINT_DEFINION Public DerivedPointsArray() As POINT_DEFINION Public MaxYOfUser As Double Public XAndYScale As Double '
Bezier eğrilerinin handikapı; polinomun derecesine bağımlısınız maalesef.. Onun için NURBS kullanmam lazım.. Burada kullanılan yöntem biraz kandırmaca.. Noktanın ağırlık faktörü önemli aslında, sıradışı noktaları kodun elimine edebilmesi lazım.. Dolayısıyla NURBS
Kod:Public Function CalculateFactorial(n_ As Integer) As Long If n_ < 0 Then MsgBox "Trying to calculate factorial of negative number" Exit Function End If If n_ = 0 Then CalculateFactorial = 1 Exit Function End If Dim FxResult As Long Static iCnt As Integer FxResult = 1 On Error Resume Next For iCnt = n_ To 1 Step -1 FxResult = FxResult * iCnt Next iCnt If Err.Number Then MsgBox "Factorial calculation (overflow) Error Description :" & Err.Description Err.Clear Exit Function End If CalculateFactorial = FxResult End Function
Rekürsif (kendi kendini çağıran anlamında) fonksiyon şeklinde faktöriyel hesabı:
Kod:Public Function Factorial(AnyInteger As Integer) As Double If AnyInteger = 0 Then Factorial = 1# Exit Function End If Factorial = CDbl(AnyInteger) * Factorial(AnyInteger - 1) End Function
Bezier Eğrisi Hesabı
Kod:'degree of polynom = n 'number of control points = n+1 'number of segments = NbrOfSegments ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''* '' B(t)=Sigma{j=0 to n} t^j * Cj '' Cj = (n!/(n-j)!) * Sigma{i=0 to j} [(-1)^(i+j) * Pi] / [i! * (j-i)!] Public Sub CalculateBezier(PointsArray() As POINT_DEFINION, NbrOfSegments As Integer) Dim n As Integer n = UBound(PointsArray) If n = 0 Then MsgBox "1 adet nokta tanımlanmış" Exit Sub End If Dim DerivedPointsQuantity As Long DerivedPointsQuantity = NbrOfSegments * n ReDim DerivedPointsArray(0 To DerivedPointsQuantity) Dim t As Double t = 0 Dim CalculatedBezierValueX As Double Dim CalculatedBezierValueY As Double Static j As Integer Dim tCounter As Long For tCounter = 0 To DerivedPointsQuantity CalculatedBezierValueX = 0# CalculatedBezierValueY = 0# For j = 0 To n CalculatedBezierValueX = CalculatedBezierValueX + t ^ j * CjFunctionX(n, j, PointsArray) CalculatedBezierValueY = CalculatedBezierValueY + t ^ j * CjFunctionY(n, j, PointsArray) Next j DerivedPointsArray(tCounter).X = CalculatedBezierValueX DerivedPointsArray(tCounter).Y = CalculatedBezierValueY t = t + (1 / DerivedPointsQuantity) Next tCounter End Sub ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''* '' Cj = (n!/(n-j)!) * Sigma{i=0 to j} [(-1)^(i+j) * Pi] / [i! * (j-i)!] '' Cj = (n!/(n-j)!) * SjFunction '' SjFunction=Sigma{i=0 to j} [(-1)^(i+j) * Pi] / [i! * (j-i)!] Public Function CjFunctionX(n As Integer, j As Integer, PointsArray() As POINT_DEFINION) As Double Dim CalculatedFactorial As Long CalculatedFactorial = CLng(CalculateFactorial(n) / CalculateFactorial(n - j)) Dim CalculatedSjFunction As Double Static i As Integer For i = 0 To j CalculatedSjFunction = CalculatedSjFunction + SjFunctionX(j, i, PointsArray) Next i CjFunctionX = CalculatedFactorial * CalculatedSjFunction End Function Public Function CjFunctionY(n As Integer, j As Integer, PointsArray() As POINT_DEFINION) As Double Dim CalculatedFactorial As Long CalculatedFactorial = CLng(CalculateFactorial(n) / CalculateFactorial(n - j)) Dim CalculatedSjFunction As Double Static i As Integer For i = 0 To j CalculatedSjFunction = CalculatedSjFunction + SjFunctionY(j, i, PointsArray) Next i CjFunctionY = CalculatedFactorial * CalculatedSjFunction End Function ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''* '' SjFunction=Sigma{i=0 to j} [(-1)^(i+j) * Pi] / [i! * (j-i)!] Public Function SjFunctionX(j As Integer, i As Integer, PointsArray() As POINT_DEFINION) As Double SjFunctionX = ((-1) ^ (i + j) * PointsArray(i).X) / (CalculateFactorial(i) * CalculateFactorial(j - i)) End Function Public Function SjFunctionY(j As Integer, i As Integer, PointsArray() As POINT_DEFINION) As Double SjFunctionY = ((-1) ^ (i + j) * PointsArray(i).Y) / (CalculateFactorial(i) * CalculateFactorial(j - i)) End Function
Form1 içine bi tane Picture1 nesnesi yerleştiriyoruz..
Kod:Private Sub Form_Initialize() MaxYOfUser = 10# XAndYScale = Form1.Picture1.ScaleHeight / MaxYOfUser MsgBox "Sol tuşa basarak noktalar belirleyin." & vbCr & "İkinci noktadan sonra Bezier eğrileri çizilecek." & vbCr & vbCr & "Grafiği temizlemek için sağ tuşa basın." End Sub
Picture1 üzerinde tıklanan nokta koordinatlarını alıyoruz..
Bezier eğrisini Picture1 üzerinde çizdiriyoruz..Kod:Private Sub Picture1_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single) Static ControlPointsCount As Integer Static Bool_GraphStarted As Boolean Static Bool_ThereIAreAtLeastTwoLines As Boolean Static LastX As Single Static LastY As Single Dim Last2Points(1) As POINT_DEFINION If Button = 1 And Not Bool_GraphStarted Then Form1.Picture1.Circle (X, Y), XAndYScale * MaxYOfUser / 100#, vbYellow LastX = X LastY = Y Bool_GraphStarted = True ElseIf Button = 1 And Bool_GraphStarted Then Form1.Picture1.Circle (X, Y), XAndYScale * MaxYOfUser / 100#, vbYellow If ControlPointsCount = 0 Then ReDim ControlPointsArray(2) With ControlPointsArray(0) .X = LastX / XAndYScale .Y = (Form1.Picture1.ScaleHeight - LastY) / XAndYScale End With With ControlPointsArray(2) .X = X / XAndYScale .Y = (Form1.Picture1.ScaleHeight - Y) / XAndYScale End With With ControlPointsArray(1) .X = (ControlPointsArray(0).X + ControlPointsArray(2).X) / 2# .Y = (ControlPointsArray(0).Y + ControlPointsArray(2).Y) / 2# End With ControlPointsCount = 2 ElseIf ControlPointsCount = 2 And Not Bool_ThereIAreAtLeastTwoLines Then ReDim Preserve ControlPointsArray(4) With ControlPointsArray(4) .X = X / XAndYScale .Y = (Form1.Picture1.ScaleHeight - Y) / XAndYScale End With With ControlPointsArray(3) .X = (ControlPointsArray(4).X + ControlPointsArray(2).X) / 2# .Y = (ControlPointsArray(4).Y + ControlPointsArray(2).Y) / 2# End With Last2Points(1).X = ControlPointsArray(4).X Last2Points(1).Y = ControlPointsArray(4).Y Last2Points(0).X = ControlPointsArray(3).X Last2Points(0).Y = ControlPointsArray(3).Y ReDim Preserve ControlPointsArray(3) DrawGraphData ReDim ControlPointsArray(1) ControlPointsArray(0).X = Last2Points(0).X ControlPointsArray(0).Y = Last2Points(0).Y ControlPointsArray(1).X = Last2Points(1).X ControlPointsArray(1).Y = Last2Points(1).Y ControlPointsCount = 2 Bool_ThereIAreAtLeastTwoLines = True ElseIf ControlPointsCount = 2 And Bool_ThereIAreAtLeastTwoLines Then ReDim Preserve ControlPointsArray(3) With ControlPointsArray(3) .X = X / XAndYScale .Y = (Form1.Picture1.ScaleHeight - Y) / XAndYScale End With With ControlPointsArray(2) .X = (ControlPointsArray(3).X + ControlPointsArray(1).X) / 2# .Y = (ControlPointsArray(3).Y + ControlPointsArray(1).Y) / 2# End With Last2Points(1).X = ControlPointsArray(3).X Last2Points(1).Y = ControlPointsArray(3).Y Last2Points(0).X = ControlPointsArray(2).X Last2Points(0).Y = ControlPointsArray(2).Y ReDim Preserve ControlPointsArray(2) DrawGraphData ReDim ControlPointsArray(1) ControlPointsArray(0).X = Last2Points(0).X ControlPointsArray(0).Y = Last2Points(0).Y ControlPointsArray(1).X = Last2Points(1).X ControlPointsArray(1).Y = Last2Points(1).Y ControlPointsCount = 2 End If LastX = X LastY = Y ElseIf Button = 2 Then Bool_GraphStarted = False Bool_ThereIAreAtLeastTwoLines = False LastX = 0# LastY = 0# ControlPointsCount = 0 Me.Picture1.Cls End If End Sub
Kod:Private Sub DrawGraphData() CalculateBezier ControlPointsArray, 4 Dim i As Integer Dim GraphPoints() As POINT_DEFINION ''Bezier egrisi çizdiriliyor ReDim GraphPoints(0 To UBound(DerivedPointsArray)) For i = 0 To UBound(DerivedPointsArray) GraphPoints(i).X = DerivedPointsArray(i).X * XAndYScale GraphPoints(i).Y = Form1.Picture1.ScaleHeight - DerivedPointsArray(i).Y * XAndYScale Next i Dim TrendColor As Long For i = 1 To UBound(GraphPoints) If GraphPoints(i - 1).Y >= GraphPoints(i).Y Then TrendColor = vbGreen Else TrendColor = vbRed End If Form1.Picture1.Line (GraphPoints(i - 1).X, GraphPoints(i - 1).Y)-(GraphPoints(i).X, GraphPoints(i).Y), TrendColor Next i End Sub