一次関数のクラス

オートシェイプなどを正確に描画しようと思ったら、昔習った数学の知識を、地底深くから掘り起こす必要があります。例えば昨日のPowerPointのマクロでは、以下の座標を求める必要がありました。

  • 二点間を結ぶ直線Aと、別の二点間を結ぶ直線Bの交点座標O
  • 座標Oを原点とする半径rの円と、直線Aの共有点(2箇所)

最初は、直線AとBが傾いていても関係なく、一般式を作成して対応しようとしたのですが、数式が複雑化したため断念しました。
その結果、昨日のマクロは

などのように、ある特殊な条件下でのみ成立するものとなってしまいました。
※この場合は、二本の線が水平線と垂直線であること。

そこで、今後のオートシェイプ操作に備えて、数学的な幾つかのパラメータを取得するクラスモジュールを準備しておくことにしました。
※既に世の中にあるかもしれませんが、自身の練習も兼ねて。

まずは、直線AとBの交点座標を求めてみました。

[クラスモジュール]名前:MathematicalFormulaClass

Option Explicit

Public x1 As Double, y1 As Double
Public x2 As Double, y2 As Double
Public x3 As Double, y3 As Double
Public x4 As Double, y4 As Double
Public x5 As Double, y5 As Double
Public x6 As Double, y6 As Double

Public Function GetSlope(x As Double, y As Double, u As Double, v As Double) As Double
    GetSlope = (y - v) / (x - u)
End Function

Public Function GetIntercept(a As Double, x As Double, y As Double) As Double
    GetIntercept = y - a * x
End Function

Public Property Get a1() As Double
    a1 = GetSlope(x1, y1, x2, y2)
End Property

Public Property Get a2() As Double
    a2 = GetSlope(x3, y3, x4, y4)
End Property

Public Property Get b1() As Double
    b1 = GetIntercept(a1, x1, y1)
End Property

Public Property Get b2() As Double
    b2 = GetIntercept(a2, x3, y3)
End Property

Public Property Get GetIntersect_x() As Double
    GetIntersect_x = (b2 - b1) / (a1 - a2)
End Property

Public Property Get GetIntersect_y() As Double
    GetIntersect_y = a1 * GetIntersect_x + b1
End Property

いずれ、3つの点からなる円AとBの共有点を求める場合があるかもしれないので、座標は6つ準備しています。

結果を、こちらのサンプルで確認しました。
f:id:Infoment:20180909151350p:plain

Option Explicit

Sub CalcTest()
    Dim MFC As MathematicalFormulaClass
    Set MFC = New MathematicalFormulaClass
        With MFC
            .x1 = 3:  .y1 = 6
            .x2 = -3: .y2 = -6
            .x3 = -4: .y3 = 9
            .x4 = 4:  .y4 = -7
        End With
        
    Dim x0 As Double
        x0 = MFC.GetIntersect_x
    Dim y0 As Double
        y0 = MFC.GetIntersect_y
        
        Debug.Print "X座標:" & x0
        Debug.Print "Y座標:" & y0
End Sub

結果、期待通りの数値が返ってきました。
f:id:Infoment:20180909151626p:plain


ただし、今回作成したものは、以下の場合に対応できていません。

  • Y軸に平行な直線の場合

そのあたりも手当てしつつ、次は(※「次回は」ではない)円と直線の共有点を求めることに挑戦です。

参考まで。