Используйте правильные ожидания загрузки страницы после каждых .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
Модификация ответа 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
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);
Это почти наверняка не самое оптимальное решение проблемы, однако оно кажется работать стабильно. Если у кого-то есть более оптимальный способ сделать это, это было бы здорово.
Я предпочитаю работать с углом, используя единицы, которые имеют степень двойки на оборот. Например, если вы используете 16-битные целые числа со знаком для представления от -180 до +180 градусов, вы можете просто взять (from-to) / num_steps для интерполяции. Сложение и вычитание углов всегда работает, поскольку двоичные значения переполняются прямо в точке перехода от 360 к 0.
В вашем случае вы, вероятно, захотите сделать математику по модулю 360. Таким образом, угловые разности вычисляются как (от- к)% 360. По-прежнему есть некоторые проблемы со знаками, которые были рассмотрены в других вопросах SO.
Извините, это было немного запутано, вот более сжатая версия:
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);
}
Кто-нибудь получил более оптимизированную версию ?