Главная страница


ru.algorithms

 
 - RU.ALGORITHMS ----------------------------------------------------------------
 From : Oleg Polubasoff                      2:5020/400     09 Nov 2001  21:04:28
 To : Serg Belyaev
 Subject : [* - гео] - середина дуги
 -------------------------------------------------------------------------------- 
 
     Привет, Серж!
 
 09.11.01  1:26, а также в 13:00 в личном письме, Serg Belyaev писал:
 
 SB> Идея Мусихина использовать ОБЕ диагонали мне понравилась
 SB> z=-i*(z2-z1)+(z1+z2) или z=-i*(z2-z1)-(z1+z2) с последующей
 SB> нормировкой.
 SB> Решение Виталия Мусихина можно чуть улучшить и уменьшить
 SB> количество проверок - см. MUS2. Самое главное - уменьшается
 SB> количество умножений на 2.
 SB> Число умножений можно еще уменьшить на 2 - см. MUS3
 
 SB> procedure mus2(Ax,Ay,Bx,By,Cx,Cy:real);
 
 [чисто паскалевские детали скипнуты]
 
 SB> if (x1*y2-x2*y1)>=0 then begin x:=x1+x2+y2-y1; y:=y1+y2+x1-x2 end
 SB> else begin x:=y2-y1-x1-x2; y:=x1-x2-y1-y2 end;
 SB> a:=2*(x*x+y*y);
 SB> if a>0 then a:=sqrt((x1*x1+y1*y1+x2*x2+y2*y2)/a);
 SB> x:=a*x+Cx; y:=a*y+Cy;
 
     Действительно. Очень логичное улучшение. Hадёжность повышается,
 а скорость, скорее всего, повышается тоже.
 Всё-таки оказалось, что можно обойтись одной проверкой (не считая очень
 не лишней проверки перед делением), одной операцией взятия корня и одним
 делением.
     Кстати, легко показать, что без корня не обойтись. Ведь ответ может
 оказаться иррациональным, даже если все исходные данные рациональны.
 
 SB> procedure mus3(Ax,Ay,Bx,By,Cx,Cy:real);
 
 [...]
 
 SB> x:=y2-y1+x1+x2; y:=x1-x2+y1+y2;
 SB> A:=y2-y1-x1-x2; B:=x1-x2-y1-y2;
 SB> if (abs(x)+abs(y))<(abs(A)+abs(B)) then begin x:=A; y:=B end;
 
     Hад этим условием я некоторое время медитировал. Условие оказалось
 корректным.
 
 SB> r:=2*(x*x+y*y);
 SB> if r>0 then r:=sqrt((x1*x1+y1*y1+x2*x2+y2*y2)/r);
 SB> x:=r*x+Cx; y:=r*y+Cy;
     Доведём до логического конца.
 
                                         // пусть CD - искомое решение
 sx = y2-y1; sy = x1-x2;                 // Cs = CD*2*sin(ACB/2)
 cx = x1+x2; cy = y1+y2;                 // Cc = CD*2*cos(ACB/2)
 
 spcx = sx+cx; spcy = sy+cy;             // spc = Cs+Cc
 smcx = sx-cx; smcy = sy-cy;             // smc = Cs-Cc
 
 spc2 = spcx*spcx + spcy*spcy;           // spc^2
 smc2 = smcx*smcx + smcy*smcy;           // smc^2
 x = 0; y = 0;
 
 if (spc2 < smc2)                        // если 180 < ACB < 360
      { x = smcx; y = smcy; k = smc2; }
 else { x = spcx; y = spcy; k = spc2; }  // если 0 <= ACB <= 180
 
                                         // spc2+smc2 = 8*CD^2
 
 if (k>0) k = sqrt((spc2+smc2)/(8*k));   // 0.35 <= k <= 0.5
 
 x *= k; y *= k;
 
     Получилось что-то похожее на бред параноика, но дыр я не вижу. :-)
 
     С уважением, Олег Полубасов.
 
 --- ifmail v.2.15dev5
  * Origin: Fidolook Express http://fidolook.da.ru (2:5020/400)
 
 

Вернуться к списку тем, сортированных по: возрастание даты  уменьшение даты  тема  автор 

 Тема:    Автор:    Дата:  
 [* - гео] - середина дуги   Oleg Polubasoff   08 Nov 2001 18:32:50 
 [* - гео] - середина дуги   Serg Belyaev   09 Nov 2001 02:26:37 
 [* - гео] - середина дуги   Oleg Polubasoff   09 Nov 2001 21:04:28 
Архивное /ru.algorithms/6577d14f9dec.html, оценка 3 из 5, голосов 10
Яндекс.Метрика
Valid HTML 4.01 Transitional