Преобразование вершин LWPOLYLINE, записанных в формате DXF

Автор Тема: Преобразование вершин LWPOLYLINE, записанных в формате DXF  (Прочитано 14636 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн bavilla

  • ADN OPEN
  • Сообщений: 12
  • Карма: 2
Да, все получилось. Пришлось немного геометрию вспоминать)

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Тогда может поделишься с народом кодом? Заодно может что-то подскажу, если увижу какие-то ошибки.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн bavilla

  • ADN OPEN
  • Сообщений: 12
  • Карма: 2
Да, конечно, сейчас оформлю и выложу

Оффлайн bavilla

  • ADN OPEN
  • Сообщений: 12
  • Карма: 2
Вот пример реализации на С того, что описано в http://www.autodesk.com/techpubs/autocad/acad2000/dxf/arbitrary_axis_algorithm_dxf_ab.htm

Код - C++ [Выбрать]
  1. struct vector_axis
  2. {
  3.   double x;
  4.   double y;
  5.   double z;
  6. };
  7.  
  8. void vector_cross_product(vector_axis v1,vector_axis v2,vector_axis &result)
  9. {
  10.   result.x = v1.y*v2.z - v1.z*v2.y;
  11.   result.y = v1.z*v2.x - v1.x*v2.z;
  12.   result.z = v1.x*v2.y - v1.y*v2.x;
  13. }
  14.  
  15. void calcOCS2WCS()
  16. {
  17.   vector_axis N,Wy,Wz;
  18.   vector_axis Ax,Ay,Az;
  19.  
  20.   //Значения кодов 210,220,230
  21.   N.x = -0.1525427977445352;
  22.   N.y = 0.6904568740017512;
  23.   N.z = 0.7071067811865475;
  24.  
  25.   Wy.x = 0.;
  26.   Wy.y = 1.;
  27.   Wy.z = 0.;
  28.  
  29.   Wz.x = 0.;
  30.   Wz.y = 0.;
  31.   Wz.z = 1.;
  32.  
  33.   if((fabs(N.x)<1/64.)&&(fabs(N.y)<1/64.))
  34.   {
  35.     vector_cross_product(Wy,N,Ax);
  36.   }
  37.   else
  38.   {
  39.     vector_cross_product(Wz,N,Ax);
  40.   }
  41.  
  42.   double mx = sqrt((Ax.x*Ax.x + Ax.y*Ax.y + Ax.z*Ax.z));
  43.   double k = 1./mx;
  44.  
  45.   Ax.x = Ax.x*k;
  46.   Ax.y = Ax.y*k;
  47.   Ax.z = Ax.z*k;
  48.  
  49.   vector_cross_product(N,Ax,Ay);
  50.  
  51.   mx = sqrt((Ay.x*Ay.x + Ay.y*Ay.y + Ay.z*Ay.z));
  52.   k = 1./mx;
  53.  
  54.   Ay.x = Ay.x*k;
  55.   Ay.y = Ay.y*k;
  56.   Ay.z = Ay.z*k;
  57.  
  58.   Az = N;
  59.  
  60.   // Точка в OCS
  61.   double OCS_X = 100.0;
  62.   double OCS_Y = 120.0;
  63.   double OCS_Z = 50.0;
  64.  
  65.   // Точка в WCS
  66.   double WCS_X;
  67.   double WCS_Y;
  68.   double WCS_Z;
  69.  
  70.   WCS_X = OCS_X*Ax.x + OCS_Y*Ay.x + OCS_Z*Az.x; //-86.967351702583287
  71.   WCS_Y = OCS_X*Ax.y + OCS_Y*Ay.y + OCS_Z*Az.y; //-69.904790521388321
  72.   WCS_Z = OCS_X*Ax.z + OCS_Y*Ay.z + OCS_Z*Az.z; //120.20815280171308
  73.  
  74. }
« Последнее редактирование: 04-03-2016, 12:55:58 от bavilla »

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
1. По поводу форматирования кода на форуме прочитай у меня в подписи.
2. Похоже ты забыл, что не только Ax нужно нормировать (делить на длину Ax), но тоже самое нужно сделать и для Ay.
3. Остался пока открытым вопрос с ненулевой группой 38 (уровнем).
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн bavilla

  • ADN OPEN
  • Сообщений: 12
  • Карма: 2
Спасибо за замечания!
По 38 группе - если я правильно понимаю, для LWPOLYLINE она задает Z-координату для всех точек полилинии. В моем примере это OCS_Z

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Я из спортивного интереса нарисовал полилинию с двумя вершинами в "хитрой" системе координат:
Цитировать
  0
LWPOLYLINE
  5
24E
330
1F
100
AcDbEntity
  8
0
100
AcDbPolyline
 90
        2
 70
     0
 43
0.0
38
10.0
10
103.3406489926814
 20
96.54382562220856
 10
206.6812979853627
 20
193.0876512444171

210
-0.6446022880805341
220
-0.4835076803238965
230
0.5922062252873951


Координаты вершин в WCS:
Цитировать
Command: ID Specify point:  X = 101.3001374     Y = -53.1972967     Z = 83.7157678
Command:  ID Specify point:  X = 209.0462978     Y = -101.5595166     Z = 161.5094733

Если твоя программа выдаст эти же результаты, то всё в порядке.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн bavilla

  • ADN OPEN
  • Сообщений: 12
  • Карма: 2
Да, считает правильно. Я добавил еще нормирование Ay(подправил в предыдущем сообщении), но для моих данных это ни на что не влияло, т.к. Ay и так получается единичным.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Подтверждаю:

Немного переделал твой код для удобства проверки:
Код - C++ [Выбрать]
  1. #include "stdafx.h"
  2. #include <conio.h>
  3. #include <math.h>
  4.  
  5. struct vector_axis
  6. {
  7.   double x, y, z;
  8. };
  9.  
  10. void vector_cross_product(vector_axis v1,vector_axis v2,vector_axis &result)
  11. {
  12.   result.x = v1.y * v2.z - v1.z * v2.y;
  13.   result.y = v1.z * v2.x - v1.x * v2.z;
  14.   result.z = v1.x * v2.y - v1.y * v2.x;
  15. }
  16.  
  17. void vector_normalize(vector_axis &v)
  18. {
  19.   double k = sqrt((v.x*v.x + v.y*v.y + v.z*v.z));
  20.   v.x /= k; v.y /= k; v.z /= k;
  21. }
  22.  
  23. void GetOCStoWCSMatrix(vector_axis norm, vector_axis &Ax, vector_axis &Ay, vector_axis &Az)
  24. {
  25.   vector_axis Wy,Wz;
  26.  
  27.   Wy.x = 0.;  Wy.y = 1.;  Wy.z = 0.;
  28.   Wz.x = 0.;  Wz.y = 0.;  Wz.z = 1.;
  29.  
  30.   if ((fabs(norm.x)<1/64.) && (fabs(norm.y)<1/64.))
  31.   {
  32.     vector_cross_product(Wy,norm,Ax);
  33.   }
  34.   else
  35.   {
  36.     vector_cross_product(Wz,norm,Ax);
  37.   }
  38.  
  39.   vector_normalize(Ax);
  40.   vector_cross_product(norm,Ax,Ay);
  41.   vector_normalize(Ay);
  42.   Az = norm;
  43. }
  44.  
  45. void TransWithMatrix(vector_axis pIn, vector_axis Ax, vector_axis Ay, vector_axis Az, vector_axis &pOut)
  46. {
  47.   pOut.x = pIn.x * Ax.x + pIn.y * Ay.x + pIn.z * Az.x;
  48.   pOut.y = pIn.x * Ax.y + pIn.y * Ay.y + pIn.z * Az.y;
  49.   pOut.z = pIn.x * Ax.z + pIn.y * Ay.z + pIn.z * Az.z;
  50. }
  51.  
  52. int _tmain(int argc, _TCHAR* argv[])
  53. {
  54.   vector_axis norm, Ax, Ay, Az;
  55.   norm.x = -0.6446022880805341;
  56.   norm.y = -0.4835076803238965;
  57.   norm.z = 0.5922062252873951;
  58.   GetOCStoWCSMatrix(norm,Ax,Ay,Az);
  59.   vector_axis p;
  60.   p.x = 103.3406489926814;  p.y = 96.54382562220856;  p.z = 10;
  61.   TransWithMatrix(p, Ax, Ay, Az, p);
  62.   _tprintf (_T("\nx=%f y=%f z=%f"), p.x, p.y, p.z);
  63.   p.x = 206.6812979853627;  p.y = 193.0876512444171;  p.z = 10;
  64.   TransWithMatrix(p, Ax, Ay, Az, p);
  65.   _tprintf (_T("\nx=%f y=%f z=%f"), p.x, p.y, p.z);
  66.   _getch();
  67.         return 0;
  68. }
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн bavilla

  • ADN OPEN
  • Сообщений: 12
  • Карма: 2
Я специально написал пример максимально близко к описанию в справке, без всякой оптимизации и проверок, чтобы тому, кто захочет воспользоваться, была понятна суть.