2014-09-21 3 views
2

У меня есть небольшая проблема с вычислением координат. Принимая во внимание профили аэродинамических профилей в двух списках со следующими примерными координатами:профиль геометрии профиля аэродинамического профиля

Пример:

x_Coordinates = [1, 0.9, 0.7, 0.5, 0.3, 0.1, 0.0, ...] 
y_Coordinates = [0, -0.02, -0.06, -0.08, -0.10, -0.05, 0.0, ...] 

Диаграмма 1: enter image description here

Единственные известные вещи о профиле являются перечислены выше, и следующие факты :

  • первая координата всегда является задней кромкой, в примере выше (x = 1, y = 0)
  • координаты всегда выполняются на нижней/нижней стороне переднего края, в приведенном выше примере (0,0), а оттуда назад к заднему краю
  • профиль не нормирован и может существовать во вращающемся форма

Теперь я хочу, чтобы определить

  1. ведущий край и
  2. развал линии.

До сих пор я всегда использовал самый маленький x-coodinate в качестве передней кромки. Однако это не будет работать в после примерного профиля, так как наименьшая координата x расположена на верхней поверхности профиля.

схема 2: enter image description here

Кто-нибудь есть идея, как я мог бы легко вычислить/определить эти данные?


редактировать

один полный образец массив данных

(1.0, 0.95, 0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.25, 0.2, 0.15, 0.1, 0.075, 0.05, 0.025, 0.0125, 0.005, 0.0, 0.005, 0.0125, 0.025, 0.05, 0.075, 0.1, 0.15, 0.2, 0.25, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 0.95, 1.0) 
(0.00095, 0.00605, 0.01086, 0.01967, 0.02748, 0.03423, 0.03971, 0.04352, 0.04501, 0.04456, 0.04303, 0.04009, 0.03512, 0.0315, 0.02666, 0.01961, 0.0142, 0.0089, 0.0, -0.0089, -0.0142, -0.01961, -0.02666, -0.0315, -0.03512, -0.04009, -0.04303, -0.04456, -0.04501, -0.04352, -0.03971, -0.03423, -0.02748, -0.01967, -0.01086, -0.00605, -0.00095) 
+1

Его немного сложно вычислить развал линию если на нижней стороне профиля нет соответствующей точки. Каков источник ваших данных? Можете ли вы предположить, что передний край - это место, где вторая деривация самая большая? – joojaa

+0

Aso можно получить полный массив данных образца? – joojaa

+0

Верно ли, что в точке переднего края [наибольшая кривизна] (http://airfoiltools.com/airfoil/naca4digit)? – dbc

ответ

2

Ну это было уже несколько лет я делаю что-то с крыльями.

У меня нет каких-либо искаженные данные крылья, как на изображении ближе всего я нашел это:

wing

  1. передний край не правильно нетривиальных крылья

    просто найти точку, где знак dx перелистывает и вычисляет

    dx(i)=x(i)-x(i-1) 
    

    затем отметьте зоны, где dx является положительным или отрицательным, и найдите среднее между ними (обычно dx==0 для этой зоны).Отметьте точку края, как ix1

  2. выпуклость линии

    для точной геометрии понадобится пересечения нормалей РезьбаКабель с каждой стороны, так:

    • начало в точке контура i
    • отливать нормальный внутри крыла
    • поиск противоположной стороны.
    • точка находкой, это нормально пересекает противоположное нормально и разделить обе нормалей на такое же расстояние

    Это выполнимо, но с безумной сложности

  3. приблизительная выпуклость линия

    менее точным способом но намного быстрее:

    1. начало набросок i
    2. найти ближайшую точку к нему на противоположной стороне
    3. вычислить среднюю точку между ними и сохранить его как неточные axis0 точек. Сделайте это для всех точек i=(0-ix1) (красная линия)
    4. делают то же самое, но начинают с противоположной стороны магазина как axis1 (темно-красный)
    5. когда сделано, то просто найти среднее между axis0,axis1

    Это может быть сделано в том же результате пути синей оси полилиния

C++, источник:

List<double> pnt; // outline 2D pnts = {x0,y0,x1,y1,x2,y2,...} 
    List<double> axis; // axis line 2D pnts = {x0,y0,x1,y1,x2,y2,...} 
    int ix0,ix1;  // edge points 

void compute() 
    { 
    int i,i0,i1; 
    double d,dd; 
    double *p0,*p1,*p2; 
    double x0,x1,y0,y1; 
    List<double> axis0,axis1; 

    // find leading edge point 
    ix0=0; ix1=0; 
    for (p0=pnt.dat,p1=p0+2,p2=p1+2,i=2;i<pnt.num;i+=2,p0=p1,p1=p2,p2+=2) 
    if ((p1[0]-p0[0])*(p2[0]-p1[0])<=0.0) { ix1=i; break; } 
    // find axis0: midpoint of i0=(0-ix1) i1=find closest from (ix1,pnt.num) 
    for (i0=2,i1=pnt.num-2;i0<ix1-2;i0+=2) 
     { 
     x0=pnt[i0+0]; 
     y0=pnt[i0+1]; 
     for (d=-1.0,i=i1;i>ix1+2;i-=2) 
      { 
      x1=pnt[i+0]; 
      y1=pnt[i+1]; 
      dd=((x1-x0)*(x1-x0))+((y1-y0)*(y1-y0)); 
      if ((d<0.0)||(dd<=d)) { i1=i; d=dd; } 
      } 
     if (d>=0.0) 
      { 
      x1=pnt[i1+0]; 
      y1=pnt[i1+1]; 
      axis0.add(0.5*(x0+x1)); 
      axis0.add(0.5*(y0+y1)); 
      } 
     } 
    // find axis1: midpoint of i0=(ix1,pnt.num) i1=find closest from (0,ix1) 
    for (i1=2,i0=pnt.num-2;i0>ix1+2;i0-=2) 
     { 
     x0=pnt[i0+0]; 
     y0=pnt[i0+1]; 
     for (d=-1.0,i=i1;i<ix1-2;i+=2) 
      { 
      x1=pnt[i+0]; 
      y1=pnt[i+1]; 
      dd=((x1-x0)*(x1-x0))+((y1-y0)*(y1-y0)); 
      if ((d<0.0)||(dd<=d)) { i1=i; d=dd; } 
      } 
     if (d>=0.0) 
      { 
      x1=pnt[i1+0]; 
      y1=pnt[i1+1]; 
      axis1.add(0.5*(x0+x1)); 
      axis1.add(0.5*(y0+y1)); 
      } 
     } 
    // find axis: midpoint of i0=<0-axis0.num) i1=find closest from <0-axis1.num) 
    axis.add(pnt[ix0+0]); 
    axis.add(pnt[ix0+1]); 
    for (i0=0,i1=0;i0<axis0.num;i0+=2) 
     { 
     x0=axis0[i0+0]; 
     y0=axis0[i0+1]; 
     for (d=-1.0,i=i1;i<axis1.num;i+=2) 
      { 
      x1=axis1[i+0]; 
      y1=axis1[i+1]; 
      dd=((x1-x0)*(x1-x0))+((y1-y0)*(y1-y0)); 
      if ((d<0.0)||(dd<=d)) { i1=i; d=dd; } 
      } 
     if (d>=0.0) 
      { 
      x1=axis1[i1+0]; 
      y1=axis1[i1+1]; 
      axis.add(0.5*(x0+x1)); 
      axis.add(0.5*(y0+y1)); 
      } 
     } 
    axis.add(pnt[ix1+0]); 
    axis.add(pnt[ix1+1]); 
    } 
  • List<double> xxx; это только моя динамический шаблон списка такой же, как double xxx[];
  • xxx.add(5); добавляет 5 к концу списка
  • xxx[7] элемент массива доступа
  • xxx.num фактического используемого размер массива
  • xxx.reset() очищает массив и установить ххй.Num = 0

[edit1] Правильные передняя кромка точка

Есть безумная мысль об этом, чтобы найти точку края на бегу плюс некоторый код тонкой настройки и результат достаточно хорошо для меня :) поэтому сначала некоторые объяснения:

enter image description here

алгоритм для оси остается такой же, но вместо ix1 связаны использование только точки, которые еще не использовали ... Также учитываются только действительные ближайшие точки (о n противоположная сторона), если ни один не найден (верхний образ изображения). С этого момента найдите самую дальнюю точку от последней оси, это точка переднего края.

Этот подход имеет гораздо более точный вывод (axis0,axis1 ближе друг к другу)

Теперь C++ код:

void compute() 
    { 
    int i,i0,i1,ii,n=4; 
    double d,dd; 
    double x0,x1,y0,y1; 
    List<double> axis0,axis1; 
    ix0=0; ix1=0; 

    // find axis0: midpoint of i0=(0-ix1) i1=find closest from (ix1,pnt.num) 
    for (i0=0,i1=pnt.num-2;i0+n<i1;i0+=2) 
     { 
     x0=pnt[i0+0]; 
     y0=pnt[i0+1]; 
     i=i1+n; if (i>pnt.num-2) i=pnt.num-2; ii=i1; 
     for (d=-1.0;i>i0+n;i-=2) 
      { 
      x1=pnt[i+0]; 
      y1=pnt[i+1]; 
      dd=((x1-x0)*(x1-x0))+((y1-y0)*(y1-y0)); 
      if ((d<0.0)||((dd<=d)&&(dd>1e-10))) { i1=i; d=dd; } 
      if ((d>=0.0)&&(dd>d)) break; 
      } 
     if (d>=0.0) 
      { 
      if (i1-i0<=n+2) { i1=ii; break; } // stop if non valid closest point found 
      x1=pnt[i1+0]; 
      y1=pnt[i1+1]; 
      axis0.add(0.5*(x0+x1)); 
      axis0.add(0.5*(y0+y1)); 
      } 
     } 
    // find leading edge point (the farest point from last found axis point) 
    x0=axis0[axis0.num-2]; 
    y0=axis0[axis0.num-1]; 
    for (d=0.0,i=i0;i<=i1;i+=2) 
     { 
     x1=pnt[i+0]; 
     y1=pnt[i+1]; 
     dd=((x1-x0)*(x1-x0))+((y1-y0)*(y1-y0)); 
     if (dd>d) { ix1=i; d=dd; } 
     } 
    axis0.add(pnt[ix1+0]); 
    axis0.add(pnt[ix1+1]); 

    // find axis1: midpoint of i0=(ix1,pnt.num) i1=find closest from (0,ix1) 
    for (i1=0,i0=pnt.num-2;i0+n>i1;i0-=2) 
     { 
     x0=pnt[i0+0]; 
     y0=pnt[i0+1]; 
     i=i1-n; if (i<0) i=0; ii=i1; 
     for (d=-1.0;i<i0-n;i+=2) 
      { 
      x1=pnt[i+0]; 
      y1=pnt[i+1]; 
      dd=((x1-x0)*(x1-x0))+((y1-y0)*(y1-y0)); 
      if ((d<0.0)||((dd<=d)&&(dd>1e-10))) { i1=i; d=dd; } 
      if ((d>=0.0)&&(dd>d)) break; 
      } 
     if (d>=0.0) 
      { 
      if (i0-i1<=n+2) { i1=ii; break; } // stop if non valid closest point found 
      x1=pnt[i1+0]; 
      y1=pnt[i1+1]; 
      axis1.add(0.5*(x0+x1)); 
      axis1.add(0.5*(y0+y1)); 
      } 
     } 
    // find leading edge point (the farest point from last found axis point) 
    x0=axis1[axis1.num-2]; 
    y0=axis1[axis1.num-1]; 
    for (d=0.0,i=i1;i<=i0;i+=2) 
     { 
     x1=pnt[i+0]; 
     y1=pnt[i+1]; 
     dd=((x1-x0)*(x1-x0))+((y1-y0)*(y1-y0)); 
     if (dd>d) { ix1=i; d=dd; } 
     } 
    axis1.add(pnt[ix1+0]); 
    axis1.add(pnt[ix1+1]); 

    // find axis: midpoint of i0=<0-axis0.num) i1=find closest from <0-axis1.num) 
    for (i0=0,i1=0;i0<axis0.num;i0+=2) 
     { 
     x0=axis0[i0+0]; 
     y0=axis0[i0+1]; 
     for (d=-1.0,i=i1;i<axis1.num;i+=2) 
      { 
      x1=axis1[i+0]; 
      y1=axis1[i+1]; 
      dd=((x1-x0)*(x1-x0))+((y1-y0)*(y1-y0)); 
      if ((d<0.0)||(dd<=d)) { i1=i; d=dd; } 
      } 
     if (d>=0.0) 
      { 
      x1=axis1[i1+0]; 
      y1=axis1[i1+1]; 
      axis.add(0.5*(x0+x1)); 
      axis.add(0.5*(y0+y1)); 
      } 
     } 
    } 

постоянная n=4 только для безопасности перекрывается поиск ближайших точек должно быть доля pnt.num. Иногда ближайшая точка до последней найденной ближайшей точки зависит от кривизны боковых сторон. Слишком большой n вызовет замедление, и если n>pnt.num/4 также может привести к недействительности вывода.

Если слишком малый, то для меньшего радиуса кривизны будет снижена точность, этот подход зависит от достаточного охвата точки. Если крыло отбирается с слишком низким количеством точек, это может привести к неточности. Исходный код 3 раза почти то же самое, вы можете выбрать, какие ix1 помнить (от первого или второго поиска) они являются соседними точками

теста профиль:

1.000000 0.000000 
0.990000 0.006719 
0.980000 0.013307 
0.970000 0.019757 
0.960000 0.026064 
0.950000 0.032223 
0.940000 0.038228 
0.930000 0.044075 
0.920000 0.049759 
0.910000 0.055276 
0.900000 0.060623 
0.890000 0.065795 
0.880000 0.070790 
0.870000 0.075604 
0.860000 0.080234 
0.850000 0.084678 
0.840000 0.088935 
0.830000 0.093001 
0.820000 0.096876 
0.810000 0.100558 
0.800000 0.104046 
0.790000 0.107339 
0.780000 0.110438 
0.770000 0.113342 
0.760000 0.116051 
0.750000 0.118566 
0.740000 0.120887 
0.730000 0.123016 
0.720000 0.124954 
0.710000 0.126702 
0.700000 0.128262 
0.690000 0.129637 
0.680000 0.130829 
0.670000 0.131839 
0.660000 0.132672 
0.650000 0.133331 
0.640000 0.133818 
0.630000 0.134137 
0.620000 0.134292 
0.610000 0.134287 
0.600000 0.134127 
0.590000 0.133815 
0.580000 0.133356 
0.570000 0.132755 
0.560000 0.132016 
0.550000 0.131146 
0.540000 0.130148 
0.530000 0.129030 
0.520000 0.127795 
0.510000 0.126450 
0.500000 0.125000 
0.490000 0.123452 
0.480000 0.121811 
0.470000 0.120083 
0.460000 0.118275 
0.450000 0.116392 
0.440000 0.114441 
0.430000 0.112429 
0.420000 0.110361 
0.410000 0.108244 
0.400000 0.106085 
0.390000 0.103889 
0.380000 0.101663 
0.370000 0.099414 
0.360000 0.097148 
0.350000 0.094870 
0.340000 0.092589 
0.330000 0.090309 
0.320000 0.088037 
0.310000 0.085779 
0.300000 0.083541 
0.290000 0.081329 
0.280000 0.079149 
0.270000 0.077006 
0.260000 0.074906 
0.250000 0.072855 
0.240000 0.070858 
0.230000 0.068920 
0.220000 0.067047 
0.210000 0.065242 
0.113262 0.047023 
0.110002 0.042718 
0.106385 0.038580 
0.102428 0.034615 
0.098146 0.030832 
0.093556 0.027239 
0.088673 0.023844 
0.083516 0.020652 
0.078101 0.017670 
0.072448 0.014904 
0.066574 0.
0.060499 0.010044 
0.054241 0.007958 
0.047820 0.006108 
0.041256 0.004497 
0.034569 0.003129 
0.027779 0.002005 
0.020907 0.001129 
0.013972 0.000502 
0.006997 0.000126 
0.000000 0.000000 
0.000000 0.000000 
-0.003997 0.000126 
-0.007972 0.000502 
-0.011907 0.001129 
-0.015779 0.002005 
-0.019569 0.003129 
-0.023256 0.004497 
-0.026820 0.006108 
-0.030241 0.007958 
-0.033499 0.010044 
-0.036574 0.
-0.039448 0.014904 
-0.042101 0.017670 
-0.044516 0.020652 
-0.046673 0.023844 
-0.048556 0.027239 
-0.050146 0.030832 
-0.051428 0.034615 
-0.052385 0.038580 
-0.053002 0.042718 
-0.053262 0.047023 
-0.053153 0.051484 
-0.052659 0.056093 
-0.051768 0.060841 
-0.050467 0.065717 
-0.048744 0.070711 
-0.046588 0.075813 
-0.043988 0.081012 
-0.040935 0.086297 
-0.037420 0.091658 
-0.033435 0.097082 
-0.028972 0.102558 
-0.024025 0.108074 
-0.018589 0.113618 
-0.012657 0.119178 
-0.006228 0.124741 
0.000704 0.130295 
0.008139 0.135828 
0.016079 0.141326 
0.024525 0.146777 
0.033475 0.152169 
0.042930 0.157488 
0.052885 0.162722 
0.063339 0.167858 
0.074287 0.172883 
0.085723 0.177784 
0.097643 0.182549 
0.110038 0.187166 
0.122902 0.191621 
0.136226 0.195903 
0.150000 0.200000 
0.164214 0.203899 
0.178856 0.207590 
0.193914 0.211059 
0.209376 0.214297 
0.225227 0.217291 
0.241453 0.220032 
0.258039 0.222509 
0.274968 0.224711 
0.292223 0.226629 
0.309787 0.228254 
0.327641 0.229575 
0.345766 0.230585 
0.364142 0.231274 
0.382749 0.231636 
0.401566 0.231662 
0.420570 0.231345 
0.439740 0.230679 
0.459054 0.229657 
0.478486 0.228274 
0.498015 0.226525 
0.517615 0.224404 
0.537262 0.221908 
0.556930 0.219032 
0.576595 0.215775 
0.596231 0.212132 
0.615811 0.208102 
0.635310 0.203684 
0.654700 0.198876 
0.673956 0.193679 
0.693050 0.188091 
0.711955 0.182115 
0.730644 0.175751 
0.749091 0.169002 
0.767268 0.161869 
0.785149 0.154357 
0.802706 0.146468 
0.819913 0.138207 
0.836742 0.129580 
0.853169 0.120591 
0.869166 0.111246 
0.884707 0.101553 
0.899768 0.091518 
0.914322 0.081149 
0.928345 0.070455 
0.941813 0.059445 
0.954701 0.048128 
0.966987 0.036514 
0.978646 0.024614 
0.989658 0.012439 
1.000000 0.000000 
+0

thx для вашего решения. Ваша идея с приближенной линией развала отличная. В настоящее время я разрабатываю инструмент, который считывает данные профиля из файлов cpacs. Эти профили могут быть нетрадиционными или могут храниться в повернутым способом. Моя главная проблема - вычислить передний фронт для таких профилей. Я нашел нетривиальное крыло на [википедии] (http: //en.wikipedia.орг/вики/Chord_% 28aeronautics% 29). Поэтому в настоящее время у меня нет данных этого профиля. –

+0

@ René В настоящее время я смотрю на точку переднего края для нетривиального крыла (я нашел только изображение без файла данных для этого профиля - это турбинное лезвие, но не крыло) портировал мой код класса старого крыла на новый компилятор для этого. Я приближаю аэродинамический профиль с помощью некоторые функции sin, cos и теперь я осматриваю один интересный способ найти краевую точку во время самого поиска оси. Забавно, как выглядит код более чем на 10 лет по сравнению с моим нынешним стилем кода :) – Spektre

+0

@ René Я сделал это ... добавил edit1 в свой ответ. Я знаю, что это немного отрывочно, но в нем также добавлен мой примерный профиль. – Spektre

Смежные вопросы