# Calculating rotation transformation to align component with direction

This VBA example demonstrates how to use the IMathUtility::CreateTransformRotateAxis SOLIDWORKS API to rotate the component and align the normal of its face with the direction from the linear edge.

As a precondition select the planar face on the first component in the assembly and linear edge on the second component in the assembly. First component must not be fixed and do not have any mates. As the result first component rotated in a way that its normal is collinear with the direction of the edge. Component is rotated around the origin.

## Explanation

In order to transform the component in the expected way it is required to calculate its transform. For that it is required to find the origin of rotation, rotation vector and an angle.

At first we create vectors of the face normal and edge direction. It is required to apply the transformation of the components to represent vectors in the same coordinate system. The angle between those vectors is a required angle of transformation.

In order to find the vector of rotation it is required to find the vector perpendicular to both normal and direction. This can be achieved by finding the cross product.

Finally point of rotation is an origin of the component transformed to the assembly coordinate system.

```Dim swApp As SldWorks.SldWorks

Sub main()

Set swApp = Application.SldWorks

Dim swModel As SldWorks.ModelDoc2

Set swModel = swApp.ActiveDoc

Dim swSelMgr As SldWorks.SelectionMgr

Set swSelMgr = swModel.SelectionManager

Dim swFace As SldWorks.Face2
Dim swEdge As SldWorks.Edge

Set swFace = swSelMgr.GetSelectedObject6(1, -1)

Dim swComp As SldWorks.Component2
Set swComp = swFace.GetComponent()
Dim swCompTransform As SldWorks.MathTransform
Set swCompTransform = swComp.Transform2

Set swEdge = swSelMgr.GetSelectedObject6(2, -1)

Dim swMathUtils As SldWorks.MathUtility
Set swMathUtils = swApp.GetMathUtility

Dim swNormalDir As SldWorks.MathVector
Set swNormalDir = swMathUtils.CreateVector(swFace.Normal)
Set swNormalDir = swNormalDir.MultiplyTransform(swCompTransform)

Dim swAlignDir As SldWorks.MathVector
Dim vLineParams As Variant
vLineParams = swEdge.GetCurve().lineParams
Dim dVec(2) As Double
dVec(0) = vLineParams(3): dVec(1) = vLineParams(4): dVec(2) = vLineParams(5)
Set swAlignDir = swMathUtils.CreateVector(dVec)
Set swAlignDir = swAlignDir.MultiplyTransform(swEdge.GetComponent().Transform2)

Dim swOrigin As SldWorks.MathPoint
Dim dOrigin(2) As Double
dOrigin(0) = 0: dOrigin(1) = 0: dOrigin(2) = 0
Set swOrigin = swMathUtils.CreatePoint(dOrigin)

Set swOrigin = swOrigin.MultiplyTransform(swCompTransform)

Dim swRotVect As SldWorks.MathVector
Set swRotVect = swNormalDir.Cross(swAlignDir)

Dim angle As Double
angle = GetAngle(swNormalDir, swAlignDir)

Dim swTransform As SldWorks.MathTransform
Set swTransform = swMathUtils.CreateTransformRotateAxis(swOrigin, swRotVect, angle)

Set swTransform = swCompTransform.Multiply(swTransform)

swComp.Transform2 = swTransform

swModel.GraphicsRedraw2

End Sub

Function GetAngle(vec1 As MathVector, vec2 As MathVector) As Double

'cos a= a*b/(|a|*|b|)
GetAngle = ACos(vec1.Dot(vec2) / (vec1.GetLength() * vec2.GetLength()))

End Function

Function ACos(val As Double) As Double

If val = 1 Then
ACos = 0
ElseIf val = -1 Then
ACos = 4 * Atn(1)
Else
ACos = Atn(-val / Sqr(-val * val + 1)) + 2 * Atn(1)
End If

End Function
```