Advertisement
starm100

opt

Apr 14th, 2020
878
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
MatLab 3.92 KB | None | 0 0
  1. %В конец вашего кода;
  2. axis equal
  3. hold on
  4.  
  5. %Попытка оптимизации без сопряжения производных
  6. %Как я понял cpoints - это средняя линия, points2 - верхняя сторона
  7. k1 = 1.35;
  8. %Лучше крайние точки дуг включить также в массивы с верхней и нижней стороной
  9. points = [pointsl(end, :); points2; pointsr(end, :)];
  10. err = @(h) erfun(h, points, k1, cpoints, 1e-6);
  11. %Когда будет условие сопряжения, через него будут узнаваться крайние высоты
  12. %В таком случае будет так:
  13.  
  14. %err = @(h) erfun([h1,h,h2], points, k1, cpoints, 1e-6);
  15. %h1, h2 - крайние высоты
  16.  
  17.  
  18. %Быстрый тест
  19. h = [0.2 0.2 0.2 0.2];
  20. err(h)
  21.  
  22. %Базовая оптимизация c ограничением по h(Функция err(hl))
  23. %Без ограничений получается ерунда
  24. [h_res, funvalue] = fmincon(err, h, [], [], [], [], [0 0 0 0], [1 1 1 1])
  25. %Проверка
  26. cp_res = cp_up(cpoints, k1, h_res, pointsl(end, :), pointsr(end, :))
  27. t = 0:0.01:1;
  28. res_points = bezierPoints(cp_res,t);
  29. plot(res_points(:,1),res_points(:,2))
  30. hold off
  31.  
  32.  
  33.  
  34. %%%Для оптимизации:
  35.  
  36. %Уравнение относительно оптимального значения параметра
  37. function [value] = eq_for_t(t,cpoints,dataPoint)
  38.     dif = bezierPoints(cpoints,t) - dataPoint;
  39.     value = dot(dif,bezierPrime(cpoints,t));
  40. end
  41.  
  42. %Метод половинного деления
  43. function [x] = bisect(fun,tol)
  44.     left = 0;
  45.     right = 1;
  46.     while (right-left)>tol
  47.         mid = (right+left)/2;
  48.         if fun(mid) == 0
  49.             x = mid;
  50.             return
  51.         elseif sign(fun(mid)) == sign(fun(left))
  52.             left=mid;
  53.         else
  54.             right=mid;
  55.         end
  56.     end
  57.     x = (right+left)/2;
  58. end
  59.  
  60.  
  61. %Рассчет меры совпадения по контрольным точкам кривой Безье
  62. %points - точки, к которым приближаем
  63. function [error] = error(cpoints, points, tol)
  64.  
  65.     %Поиск оптимального t для множества точек
  66.     optimal_t = zeros(length(points));
  67.     for i=1:length(points)
  68.         point = points(i,:);
  69.         funn = @(x) (eq_for_t(x,cpoints,point));
  70.         optimal_t(i) = bisect(funn,tol);
  71.     end
  72.    
  73.     %Рассчет ошибки как суммы расстояний, деленной на кол-во точек
  74.     curvePoints = bezierPoints(cpoints,optimal_t);
  75.     distVectors = (curvePoints - points);
  76.     error = 0;
  77.     for i=1:length(distVectors)
  78.         error = error + norm(distVectors(i, :));
  79.     end
  80.     error = error / length(distVectors);
  81. end  
  82.    
  83. %Получение координат контрольных точек из высот и коэф.сгущения
  84. function [cp_up] = cp_up(cp_mid,k1,h1,st_point,end_point)
  85.     %Из вашего кода
  86.     n1 = length(h1) + 2;
  87.     s1 = 1 / (k1^(n1 - 2));
  88.     t1 = zeros(n1);
  89.     cp_up = zeros([n1, 2]);
  90.     for i = 2:n1
  91.         t1(i) = k1^(i - 2) * s1;
  92.     end
  93.     midPoints = bezierPoints(cp_mid,t1);
  94.     cp_up(1, :) = st_point;
  95.     cp_up(n1, :) = end_point;
  96.     for i = 2 : (n1 - 1)
  97.         f = bezierPrime(cp_mid,t1(i));
  98.         cp_up(i, 2) = midPoints(i, 2) + h1(i-1) / sqrt(1 + (f(1, 2))^2);
  99.         cp_up(i, 1) = midPoints(i, 1) + sqrt(h1(i-1)^2 - (cp_up(i, 2) - midPoints(i, 2))^2);
  100.     end
  101. end
  102.  
  103. %Функция, непосредственно загружаемая в оптимизатор
  104. function [value] = erfun(h, points, coef, cp_mid, bisect_tol)
  105.     %Пока только для верхних, но это легко расширяется
  106.     cpCurve = cp_up(cp_mid, coef, h, points(1, :), points(end, :));
  107.     value = error(cpCurve, points, bisect_tol);
  108. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement