3章:VBAのプログラムリスト

  1. 非球面レンズのVBAのプログラムリスト
     2章:非球面レンズの光線追跡計算式をVBAで書くと以下のようになります。

    'グローバル変数の定義
    Dim N(60) As Double, Rr(60) As Double, D(60) As Double, X(60) As Double
    Dim U(60) As Double, Z(60) As Double, Ox(60) As Double
    Dim Ki(60) As Double, A4i(60) As Double, A6i(60) As Double, A8i(60) As Double, A10i(60) As Double
    Dim NUMB As Integer
    Dim Fb(60) As Double, F(60) As Double, OL(60) As Double

    'メインルーチン Sub 非球面レンズ計算実行()
     ASN = ActiveSheet.Name
     Sheets(ASN).Select

     Dia = Sheets(ASN).Cells(7, 3).Value
     Tc = Sheets(ASN).Cells(8, 3).Value
     N0 = Sheets(ASN).Cells(9, 3).Value
     N1 = Sheets(ASN).Cells(10, 3).Value
     Tg = Sheets(ASN).Cells(11, 3).Value
     Dg = Sheets(ASN).Cells(12, 3).Value
     NJ = Sheets(ASN).Cells(13, 3).Value
     WL = Sheets(ASN).Cells(14, 3).Value

     R_1 = Sheets(ASN).Cells(17, 3).Value
     K_1 = Sheets(ASN).Cells(18, 3).Value
     A4_1 = Sheets(ASN).Cells(19, 3).Value
     A6_1 = Sheets(ASN).Cells(20, 3).Value
     A8_1 = Sheets(ASN).Cells(21, 3).Value
     A10_1 = Sheets(ASN).Cells(22, 3).Value

     R_2 = Sheets(ASN).Cells(17, 4).Value
     K_2 = Sheets(ASN).Cells(18, 4).Value
     A4_2 = Sheets(ASN).Cells(19, 4).Value
     A6_2 = Sheets(ASN).Cells(20, 4).Value
     A8_2 = Sheets(ASN).Cells(21, 4).Value
     A10_2 = Sheets(ASN).Cells(22, 4).Value

     '正方向入射特性評価
     NUMB = 5
     N(0) = 1
     D(0) = 0
     Ox(0) = 0
     Rr(0) = 0
     Ki(0) = 0
     A4i(0) = 0
     A6i(0) = 0
     A8i(0) = 0
     A10i(0) = 0

     N(1) = N0
     D(1) = D(0) + Tc
     Ox(1) = 0
     Rr(1) = 1 / R_1
     Ki(1) = K_1
     A4i(1) = A4_1
     A6i(1) = A6_1
     A8i(1) = A8_1
     A10i(1) = A10_1

     N(2) = 1
     D(2) = D(1) + Dg
     Ox(2) = 0
     Rr(2) = 1 / R_2
     Ki(2) = K_2
     A4i(2) = A4_2
     A6i(2) = A6_2
     A8i(2) = A8_2
      A10i(2) = A10_2

     N(3) = N1
     D(3) = D(2) + Tg
     Ox(3) = 0
     Rr(3) = 0
     Ki(3) = 0
     A4i(3) = 0
     A6i(3) = 0
     A8i(3) = 0
     A10i(3) = 0

     N(4) = 1
     D(4) = D(3) + 0
     Ox(4) = 0
     Rr(4) = 0
     Ki(4) = 0
     A4i(4) = 0
     A6i(4) = 0
     A8i(4) = 0
     A10i(4) = 0

     For i = 1 To 10
      For j = 0 To 50
       Sheets(ASN).Cells(27 + j, i).Formula = ""
      Next j
     Next i

     U(0) = 0
     For i = 0 To NJ
      If i = 0 Then
       X(0) = 0.001
      Else
       X(0) = i * Dia / (2 * NJ)
      End If
      CAL '光線追跡実行
      Fb(i) = -D(NUMB - 1) + Z(NUMB - 1) + X(NUMB - 1) / Tan(U(NUMB - 1)) 'バックフォーカス
      F(i) = X(0) / Sin(U(NUMB - 1)) '焦点距離
      OLi = 0
      For k = 0 To NUMB - 2 '光路長の集計
       OLi = OLi + (Z(k + 1) - Z(k)) * N(k) / Cos(U(k))
      Next k
      OLi = OLi + (D(NUMB - 1) - Z(NUMB - 1) + Fb(0)) * N(NUMB - 1) / Cos(U(NUMB - 1))
      If i = 0 Then
       OL0 = OLi
      End If
      X(NUMB) = X(NUMB - 1) - Tan(U(NUMB - 1)) * (D(NUMB - 1) - Z(NUMB - 1) + Fb(0))
      OL(i) = (OLi - OL0 + Sin(U(NUMB - 1)) * X(NUMB)) * 1000000 / WL '波面収差計算
      Sheets(ASN).Cells(27 + i, 1).Value = i / NJ
      Sheets(ASN).Cells(27 + i, 2).Value = X(0)
      Sheets(ASN).Cells(27 + i, 3).Value = F(i)
      Sheets(ASN).Cells(27 + i, 4).Value = Fb(i) + Tg + Dg
      Sheets(ASN).Cells(27 + i, 5).Value = OL(i)
      Sheets(ASN).Cells(27 + i, 6).Value = U(NUMB - 1)
     Next i

     '逆方向入射特性評価
      NUMB = 5  N(0) = 1
     D(0) = 0
     Ox(0) = 0
     Rr(0) = 0
     Ki(0) = 0
     A4i(0) = 0
     A6i(0) = 0
     A8i(0) = 0
     A10i(0) = 0

     N(1) = N1
     D(1) = D(0) + Tg
     Ox(1) = 0
     Rr(1) = 0
     Ki(1) = 0
     A4i(1) = 0
     A6i(1) = 0
     A8i(1) = 0
     A10i(1) = 0

     N(2) = 1
     D(2) = D(1) + Dg
     Ox(2) = 0
     Rr(2) = 0
     Ki(2) = 0
     A4i(2) = 0
     A6i(2) = 0
     A8i(2) = 0
     A10i(2) = 0

     N(3) = N0
     D(3) = D(2) + Tc
     Ox(3) = 0
     Rr(3) = -1 / R_2
     Ki(3) = K_2
     A4i(3) = -A4_2
     A6i(3) = -A6_2
     A8i(3) = -A8_2
     A10i(3) = -A10_2

     N(4) = 1
     D(4) = D(3) + 0
     Ox(4) = 0
     Rr(4) = -1 / R_1
     Ki(4) = K_1
     A4i(4) = -A4_1
     A6i(4) = -A6_1
     A8i(4) = -A8_1
     A10i(4) = -A10_1

     U(0) = 0
     For i = 0 To NJ
      If i = 0 Then
       X(0) = 0.001
      Else
       X(0) = i * Dia / (2 * NJ)
      End If
      CAL '光線追跡実行
      Fb(i) = -D(NUMB - 1) + Z(NUMB - 1) + X(NUMB - 1) / Tan(U(NUMB - 1))
      F(i) = X(0) / Sin(U(NUMB - 1))
      OLi = 0
      For k = 0 To NUMB - 2
       OLi = OLi + (Z(k + 1) - Z(k)) * N(k) / Cos(U(k))
      Next k
      OLi = OLi + (D(NUMB - 1) - Z(NUMB - 1) + Fb(0)) * N(NUMB - 1) / Cos(U(NUMB - 1))
      If i = 0 Then
       OL0 = OLi
      End If
      X(NUMB) = X(NUMB - 1) - Tan(U(NUMB - 1)) * (D(NUMB - 1) - Z(NUMB - 1) + Fb(0))
      OL(i) = (OLi - OL0 + Sin(U(NUMB - 1)) * X(NUMB)) * 1000000 / WL

      Sheets(ASN).Cells(27 + i, 7).Value = F(i)
      Sheets(ASN).Cells(27 + i, 8).Value = Fb(i)
      Sheets(ASN).Cells(27 + i, 9).Value = OL(i)
      Sheets(ASN).Cells(27 + i, 10).Value = U(NUMB - 1)
     Next i
    End Sub

    'ユーザ定義関数 非球面レンズ面の関数
    Function Fz(y, R1, k, A4, A6, A8, A10)
     Fx1 = y ^ 2 / (R1 * (1 + Sqr(1 - (1 + k) * y ^ 2 / R1 ^ 2)))
     Fx2 = A4 * y ^ 4 + A6 * y ^ 6 + A8 * y ^ 8 + A10 * y ^ 10
     Fz = Fx1 + Fx2
    End Function

    'ユーザ定義関数 ニュートン法のための中間関数
    Function Gx(X1, X0, U0, Ox1, D0, Z0, R1, k, A4, A6, A8, A10)
     Gx = X1 - X0 + Tan(U0) * (Fz(X1 - Ox1, R1, k, A4, A6, A8, A10) + D0 - Z0)
    End Function

    'ユーザ定義関数 Ziを求める
    Function Zi(X0, U0, Ox1, D0, Z0, Rr1, k, A4, A6, A8, A10)
     If Rr1 = 0 Then
      'Rr1 = 0(Rk=∞)の場合の処理
      Zi = D0
     Else
      'Rr1 = 0(Rk=∞)以外の場合の処理
      R1 = 1 / Rr1
      dx = 0.001
      X1 = X0
       'ニュートン法でX1を求める
      For i = 1 To 10
       Gx0 = Gx(X1, X0, U0, Ox1, D0, Z0, R1, k, A4, A6, A8, A10)
       Gxm = Gx(X1 - dx, X0, U0, Ox1, D0, Z0, R1, k, A4, A6, A8, A10)
       Gxp = Gx(X1 + dx, X0, U0, Ox1, D0, Z0, R1, k, A4, A6, A8, A10)
       X1 = X1 - Gx0 * 2 * dx / (Gxp - Gxm)
      Next i
      'Z1を求める
      Zi = Fz(X1 - Ox1, R1, k, A4, A6, A8, A10) + D0
     End If
    End Function

    'ユーザ定義関数 面の傾斜を求める
    Function TSx(X1, R1, k, A4, A6, A8, A10)
     dx = 0.001
     Xp = X1 + dx
     Fxp = Fz(Xp, R1, k, A4, A6, A8, A10)
     Xm = X1 - dx
     Fxm = Fz(Xm, R1, k, A4, A6, A8, A10)
     TSx = (Fxp - Fxm) / (2 * dx)
    End Function

    'ユーザ定義関数 Uiを求める
    Function Ui(X1, Rr1, k, A4, A6, A8, A10, N0, N1, U0)
     If Rr1 = 0 Then
      Sx = 0
     Else
      R1 = 1 / Rr1
      Pix = Application.WorksheetFunction.Pi()
      AL = TSx(X1, R1, k, A4, A6, A8, A10)
      Sx = Atn(TSx(X1, R1, k, A4, A6, A8, A10))
     End If
     Sn01 = (N0 / N1) * Sin(Sx - U0)
     If Abs(Sn01) < 1 Then
      Ui = Sx - Application.WorksheetFunction.Asin(Sn01)
     Else
      Ui = 0.0000000001
     End If
    End Function

    '光線追跡サブルーチン Z(i + 1)、X(i + 1)、U(i + 1)を求める
    Sub CAL()
     For i = 0 To NUMB - 2
      If (Rr(i + 1) = 0) Then
       Z(i + 1) = D(i)
       X(i + 1) = X(i) - Tan(U(i)) * (Z(i + 1) - Z(i))
       Sx = 0
       U(i + 1) = Sx - Application.WorksheetFunction.Asin(N(i) * Sin(Sx - U(i)) / N(i + 1))
      Else
       Z(i + 1) = Zi(X(i), U(i), Ox(i + 1), D(i), Z(i), Rr(i + 1), Ki(i + 1), A4i(i + 1), A6i(i + 1), A8i(i + 1), A10i(i + 1))
       X(i + 1) = X(i) - Tan(U(i)) * (Z(i + 1) - Z(i))
       U(i + 1) = Ui(X(i + 1), Rr(i + 1), Ki(i + 1), A4i(i + 1), A6i(i + 1), A8i(i + 1), A10i(i + 1), N(i), N(i + 1), U(i))
      End If
     Next i
    End Sub


  2. 解説
    1. グローバル変数の定義
       グローバル変数を定義しています。

    2. メインルーチン
       「計算実行ボタン」を押すと実行されます。
       グローバル変数に入力パラメータを設定します。
       光線追跡を実行します。
       光路長と波面収差、焦点距離、バックフォーカスを計算します。
       計算結果を表示します。

    3. ユーザ定義関数 非球面レンズ面の関数
       非球面レンズ面の関数を定義しています。

    4. ユーザ定義関数 ニュートン法のための中間関数
       ニュートン法のための中間関数を定義しています。

    5. ユーザ定義関数 Ziを求める
       ニュートン法によりZiを求めます。

    6. ユーザ定義関数 Uiを求める
       Uiを求めます。

    7. 光線追跡サブルーチン Z(i + 1)、X(i + 1)、U(i + 1)を求める
       光線追跡を実行します。



4章:非球面レンズの光線追跡フリーソフトに行く。

トップページに戻る。