Интерполяция вращения

Используйте правильные ожидания загрузки страницы после каждых .Navigate и .Click.

While ie.Busy Or ie.readyState < 4: DoEvents: Wend

Кроме того, вы можете обернуть элементы, которые выдают ошибки, связанные с таймингами, в синхронизированные циклы, которые пытаются установить ссылку на объект

Dim t As Date, ele As Object
Const MAX_WAIT_SEC As Long = 10

t = Timer
Do
    On Error Resume Next
    Set ele = doc.getElementById("ContentPlaceHolder1_GridView1_chkboxSelectAll")
    On Error GoTo 0
    If Timer - t > MAX_WAIT_SEC Then Exit Do
Loop While ele Is Nothing

If Not ele Is Nothing Then
    ele.Click
End If
27
задан Rob 2 September 2016 в 12:23
поделиться

4 ответа

Модификация ответа user151496 (оригинал был в градусах и также предоставлении мне неправильный вывод):

 def interp_angle(theta_1, theta_2, ratio):
    shortest_angle = ((((theta_2 - theta_1) % (np.pi*2)) + np.pi) % (np.pi*2)) - np.pi
    return (theta_1 + shortest_angle * ratio) % (np.pi*2)

Тесты: Выполнение с

theta1, theta2 = 0, 0.5
print('Average of {:.4g}pi rad and {:.4g}pi rad = {:.4g}pi rad'.format(theta1, theta2, interp_angle(theta1*np.pi, theta2*np.pi, 0.5)/np.pi))
theta1, theta2 = 0, 0.99
print('Average of {:.4g}pi rad and {:.4g}pi rad = {:.4g}pi rad'.format(theta1, theta2, interp_angle(theta1*np.pi, theta2*np.pi, 0.5)/np.pi))
theta1, theta2 = 0, 1.01
print('Average of {:.4g}pi rad and {:.4g}pi rad = {:.4g}pi rad'.format(theta1, theta2, interp_angle(theta1*np.pi, theta2*np.pi, 0.5)/np.pi))
theta1, theta2 = 0.1, -0.1
print('Average of {:.4g}pi rad and {:.4g}pi rad = {:.4g}pi rad'.format(theta1, theta2, interp_angle(theta1*np.pi, theta2*np.pi, 0.5)/np.pi))
theta1, theta2 = 0.1, 2-0.1
print('Average of {:.4g}pi rad and {:.4g}pi rad = {:.4g}pi rad'.format(theta1, theta2, interp_angle(theta1*np.pi, theta2*np.pi, 0.5)/np.pi))

Дает мне:

Average of 0pi rad and 0.5pi rad = 0.25pi rad
Average of 0pi rad and 0.99pi rad = 0.495pi rad
Average of 0pi rad and 1.01pi rad = 1.505pi rad
Average of 0.1pi rad and -0.1pi rad = 0pi rad
Average of 0.1pi rad and 1.9pi rad = 0pi rad
0
ответ дан 28 November 2019 в 04:48
поделиться

NB: с использованием кода C #

После сумасшедших поисков в моей голове, вот что я придумал. Обычно предполагается выполнить обертывание 0–360 в последнюю минуту. Работайте внутри со значениями за пределами 0–360, а затем заключите их в 0–360 в момент, когда значение запрашивается у функции.

В точке, где вы выбираете начальную и конечную точки, вы выполняете следующее:

float difference = Math.Abs(end - start);
if (difference > 180)
{
    // We need to add on to one of the values.
    if (end > start)
    {
        // We'll add it on to start...
        start += 360;
    }
    else
    {
        // Add it on to end.
        end += 360;
    }
}

Это дает вам фактическое начальное и конечное значения, которые могут быть за пределами 0-360 ...

У нас есть обернуть функцию, чтобы гарантировать, что значение находится в диапазоне от 0 до 360 ...

public static float Wrap(float value, float lower, float upper)
{
    float rangeZero = upper - lower;

    if (value >= lower && value <= upper)
        return value;

    return (value % rangeZero) + lower;
}

Затем, когда вы запрашиваете текущее значение у функции:

return Wrap(Lerp(start, end, amount), 0, 360);

Это почти наверняка не самое оптимальное решение проблемы, однако оно кажется работать стабильно. Если у кого-то есть более оптимальный способ сделать это, это было бы здорово.

3
ответ дан 28 November 2019 в 04:48
поделиться

Я предпочитаю работать с углом, используя единицы, которые имеют степень двойки на оборот. Например, если вы используете 16-битные целые числа со знаком для представления от -180 до +180 градусов, вы можете просто взять (from-to) / num_steps для интерполяции. Сложение и вычитание углов всегда работает, поскольку двоичные значения переполняются прямо в точке перехода от 360 к 0.

В вашем случае вы, вероятно, захотите сделать математику по модулю 360. Таким образом, угловые разности вычисляются как (от- к)% 360. По-прежнему есть некоторые проблемы со знаками, которые были рассмотрены в других вопросах SO.

1
ответ дан 28 November 2019 в 04:48
поделиться

Извините, это было немного запутано, вот более сжатая версия:

    public static float LerpDegrees(float start, float end, float amount)
    {
        float difference = Math.Abs(end - start);
        if (difference > 180)
        {
            // We need to add on to one of the values.
            if (end > start)
            {
                // We'll add it on to start...
                start += 360;
            }
            else
            {
                // Add it on to end.
                end += 360;
            }
        }

        // Interpolate it.
        float value = (start + ((end - start) * amount));

        // Wrap it..
        float rangeZero = 360;

        if (value >= 0 && value <= 360)
            return value;

        return (value % rangeZero);
    }

Кто-нибудь получил более оптимизированную версию ?

13
ответ дан 28 November 2019 в 04:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: