在VB6中是否有其他方法可以将点从轴向转换为投影平面?

时间:2019-05-15 17:22:18

标签: geometry transformation plane

(请注意,我也已将其发布到Yahoo! Groups上的Visual Basic 6编程列表中,但是自2017年以来似乎已经死了,所以我想我也将其发布在这里。)

我最近接管了一个正在工作的VB6程序,该程序具有一个例程,可以在给定轴点,导程测量,投影角,矢量(初始角,最终角)的情况下,将数据点从轴向平面转换为投影平面,渐变)和投影点。它被编写为一个返回布尔值以指示其是否成功的函数。

它必须从轴向计算旋转角度,然后使用牛顿-拉夫森迭代法确定该角度的值。它设置了执行此操作的30次迭代的上限,但是对于某些参数集,它无法在这30次迭代中找到解决方案。

请问有人知道执行此转换的替代方法吗?该程序用于驱动计算出数据点的CNC机床,我相信这些参数是有效的,只是所使用的方法阻止了它的进行。

我添加了日志记录输出代码以跟踪问题,发现它归结为轴向平面和投影平面之间的转换,并且投影角度具有特定的上限值(它也使用该值的+/-裕度作为过程的一部分)。

迭代代码无法找到在设定的最大尝试次数(30)之内的设定公差范围内的解决方案。

我尝试增加最大尝试次数,减少增量,增加容差,并减少所应用的边距值,但到目前为止,我没有做过任何工作,或者重复了相同的错误。

我期望输出是轮廓平面的数组,这些轮廓平面位于投影平面上,并且使用提供的导程测量和投影角度等于提供的轴向平面点,但是我遇到了一些错误,这些错误指示迭代过程无法找到最多30次尝试的解决方案。

编辑后添加:

我已经基于VB6代码编写了以下伪代码,以尝试解释该例程的工作方式:

    'AxialPoint, ProjectedPoint: structures with ProfileRadius, ProfileWidth, 
    'NormalAngle, UnwrapAngle and Attribute fields
    'Lead: lead measurement
    'ProjectionAngle: projection angle onto the projected plane in degrees
    'Vector(): provides initial value of Beta, Last Beta value found, Last 
    'gradient) - set by the calling routine as (0, 0, 0) in this case
    'Beta is the angle of rotation from the axial plane
    Function AxialToProjected(AxialPoint, Lead, ProjectionAngle, Vector(), 
    ProjectedPoint):
        LeadAngle := Atn(Lead / (2 * PI * AxialPoint.ProfileRadius)) 'radians
        SA := Sin(LeadAngle)
        CA = Cos(LeadAngle)
        CT := -CosD(AxialPoint.NormalAngle)
        ST := SinD(AxialPoint.NormalAngle)
        SG := SinD(ProjectionAngle)
        CG := CosD(ProjectionAngle)
        C1 := SA * CG * CT
        C2 := CA * CG * ST
        C3 := CA * SG * CT
        Iteration := 0
        FBeta := 0.0001
        While (Abs(FBeta) >= 0.0001) And (Iteration < 9) Do
            NewValue(Beta, OldBeta, FBeta, Increment:=0.1, Gradient, SVB(), 
                Iteration, Multiplier:=10)
            SB := Sin(Beta)
            CB := Cos(Beta)
            OldFBeta := FBeta
            FBeta := C1 * CB + C2 * SB - C3
            If Iteration >= 2 Then
              Gradient := (Beta - OldBeta) / (FBeta - OldFBeta)
            End If
        End While
        If (Abs(FBeta) > 0.0001) Then
            'The code reaches this point with the specific parameters
            Report "Iteration failed to find a solution within 30 tries" error
        Else
            'The code doesn't reach this point
            X3 := Beta * Lead / 2 * PI + AxialPoint.ProfileWidth
            With ProjectedPoint Do
                .ProfileWidth := X3 * CG - AxialPoint.ProfileRadius * SB * SG
                .ProfileRadius := AxialPoint.ProfileRadius * CB
                .NormalAngle := ATan2(CA * CB * CG * ST - SA * SB * CG * CT, 
                    -CA * CT) * RadToDeg
                .Attribute := AxialPoint.Attribute
                .UnwrapAngle := AxialPoint.UnwrapAngle
            End With
        End If
    End AxialToProjected()

SinD()和CosD()接受一个角度(度)并将其转换为弧度,然后再将其传递给正常的Sin()和Cos()函数。

NewValue()例程在增加Iteration值的同时,使用FBeta,Increment,Gradient,SVB()和Multiplier根据OldBeta的值计算Beta的新值:

    'Beta: current axial plane rotation angle estimate
    'OldBeta: previous current axial plane rotation angle estimate
    'FBeta: gradient of tangent to the normal
    'Increment: increment size to adjust Beta by
    'Gradient: gradient for the Newton method
    NewValue(Beta, OldBeta, FBeta, Increment, Gradient, SVB(), Iteration, 
    Multiplier):
        If Iteration > 2 Then
            MaxChange := Abs(Increment * Multiplier)
            Change := -FBeta * Gradient
            If Abs(Change) > MaxChange Then
                Beta := Beta + TransferSign(MaxChange, Change)
                'TransferSign() will return -MaxChange if Change < 0 or
                'MaxChange if Change >= 0
            Else
                Beta := Beta + Change
            End If
        ElseIf Iteration = 2 Then
            If SVB(3) = 0 Then
                Beta := SVB(1) + Increment
            Else
                Beta := -FBeta * SVB(3)
            End If
        Else
            Beta := SVB(1)  'Set Beta to initial value
        End If
    End NewValue()

稍后我将上传一个图,因为我需要弄清楚如何从我的涂鸦中绘制它:)

只是添加一些额外的上下文,该例程用于使用CNC机器计算ZA和ZN型蠕虫的点数。

每种类型只有一组特定的参数会导致错误发生,我相信这是由于初始估计值离根太远而无法在30次尝试限制内解决的,但我不是确定如何得出更好的初始估算值。

0 个答案:

没有答案