Překlad C++ kódu do Delphi (6,7)

Autor Téma: Překlad C++ kódu do Delphi (6,7)  (Přečteno 2024 krát)

Offline age.new

  • Plnoletý
  • ***
  • Příspěvků: 115
  • Karma: 0
Překlad C++ kódu do Delphi (6,7)
« kdy: 13-04-2015, 10:10:45 »
Dobrý den,
mohl bych požádat zkušenější programátory o pomoc s překladem krátkého C++ kódu do Delphi? Jedná se o kreslení spline křivky z DXF souboru. Původní zdrojové soubory jsou zde:
https://github.com/JamesBremner/DXF_Viewer/blob/master/src/Spline.cpp
https://github.com/JamesBremner/DXF_Viewer/blob/master/src/Spline.h


Spline.cpp má následující funkce:
CSpline::Read
CSpline::Generate
CSpline::MatrixSolve
CSpline::getDraw

((Funkce Read čte GROUP kódy z DXF formátu. Vytahují se zde hodnoty pro SPLINE entity, tj. Fit body, vrtstva atd... Generate a MatrixSolve vytažené Fit body poskládá a interpoluje zbylé body které leží mezi. Funkce getDraw pak vše nakreslí.))

Funkci Read mám již vyřešenou, na výstupu je pole tzv. Fit bodů kterými je "popsána" spline křivka. Trápí mě funkce Generate a MatrixSolve, jelikož jsou zde mě neznámé C++ příkazy. Funkci getDraw si pak už nějak vyřeším (bez ApplyScale atd...).

Pomohl by mi někdo vyřešit tento problém?
Jinak pod odkazem https://github.com/JamesBremner/DXF_Viewer/blob/master/src jsou i další zdrojáky pro čtení jiných DXF entit, pokud by to někoho zajímalo.

Děkuji.
 
« Poslední změna: 13-04-2015, 10:19:39 od age.new »

Offline Mi.Chal.

  • Guru
  • *****
  • Příspěvků: 574
  • Karma: 25
Re:Překlad C++ kódu do Delphi (6,7)
« Odpověď #1 kdy: 13-04-2015, 11:17:47 »
Funkci Read mám již vyřešenou, na výstupu je pole tzv. Fit bodů kterými je "popsána" spline křivka. Trápí mě funkce Generate a MatrixSolve, jelikož jsou zde mě neznámé C++ příkazy. Funkci getDraw si pak už nějak vyřeším (bez ApplyScale atd...).

Tak sem napiš co konkrétně nevíš. Já tam nic zvláštního neviděl. Delphi jsem už teda dlouho neviděl, ale vectoru odpovídá asi TList (prostě něco kam můžeš přidávat prvky a ono se to samo zvětšuje), push_back znamená přidání na konec (takže asi Add).

* jsou dereference (v pascalu ^), delete je uvolnění paměti proměnné, delete [] pro pole

Offline age.new

  • Plnoletý
  • ***
  • Příspěvků: 115
  • Karma: 0
Re:Překlad C++ kódu do Delphi (6,7)
« Odpověď #2 kdy: 13-04-2015, 11:41:44 »
Dobře. Pokusím se popsat čemu nerozumím, i když by možná napsání celých funkcí od začátku bylo přehlednější a jistějní ... když vložím C++ kód do bloku pro CODE, tak složené závorky (alias begin a end) znepřehlední čitelnost kódu :(

Deklarace proměnných:

  vector<float> k; // k : array of single;
  vector< vector<float> > Mat( 3, vector<float>(m_FitPointCount) ); // co to je?
  float* Work = new float[m_FitPointCount]; // co to je?
  float* WorkB = new float[m_FitPointCount]; // co to je?

Díky za případné rady.

// musis vybrat zvyrazneni syntaxe C++, vychozi je Delphi ... <z>
Kód: C++ [Vybrat]
  1.   vector<float> k; //  k : array of single;
  2.   vector< vector<float> > Mat( 3, vector<float>(m_FitPointCount) ); //  co to je?
  3.   float* Work = new float[m_FitPointCount]; //  co to je?
  4.   float* WorkB = new float[m_FitPointCount]; //  co to je?
« Poslední změna: 13-04-2015, 16:16:46 od < z > »

Offline pepak

  • Guru
  • *****
  • Příspěvků: 1326
  • Karma: 30
    • Pepak.net
Re:Překlad C++ kódu do Delphi (6,7)
« Odpověď #3 kdy: 13-04-2015, 12:47:12 »
  vector< vector<float> > Mat( 3, vector<float>(m_FitPointCount) ); // co to je?
vector<float> je něco jako array of float, ale navíc s funkcemi pro automatické zvětšování pole, mazání prvků v poli atd. Tj. něco jako TList, jak psal Mi.Chal, jen to nepracuje s TObject ale s float.

vector<vector<float>> je něco jako TList, akorát že to nepravuje s TObject ale s vector<float>.

Pravděpodobně to používají jako dynamicky alokované dvourozměrné pole floatů, i když proti klasickému 2D poli to má jisté rozdíly.

Citace
  float* Work = new float[m_FitPointCount]; // co to je?
Kód: Delphi [Vybrat]
  1. Work: ^array[0..m_FitPointCount-1] of float

Offline Mi.Chal.

  • Guru
  • *****
  • Příspěvků: 574
  • Karma: 25
Re:Překlad C++ kódu do Delphi (6,7)
« Odpověď #4 kdy: 13-04-2015, 12:59:54 »
vector<float> je něco jako array of float, ale navíc s funkcemi pro automatické zvětšování pole, mazání prvků v poli atd. Tj. něco jako TList, jak psal Mi.Chal, jen to nepracuje s TObject ale s float.

vector<vector<float>> je něco jako TList, akorát že to nepravuje s TObject ale s vector<float>.

Delphi už by měly umět generika taky, viz třeba http://docwiki.embarcadero.com/CodeExamples/XE7/en/Generics_Collections_TList_%28Delphi%29, takže by mělo jít TList<float>

Offline age.new

  • Plnoletý
  • ***
  • Příspěvků: 115
  • Karma: 0
Re:Překlad C++ kódu do Delphi (6,7)
« Odpověď #5 kdy: 13-04-2015, 13:03:38 »
EDIT: už mi to došlo ... je to něco jako vícerozměrné pole (array of array of single)

Díky za rady. Zkusím to nějak sepsat do verze D6. Jen mi jetě není jasné co s:
vector< vector<float> >Mat( 3, vector<float>(m_FitPointCount) );

Díky
« Poslední změna: 13-04-2015, 13:43:21 od age.new »

Offline age.new

  • Plnoletý
  • ***
  • Příspěvků: 115
  • Karma: 0
Re:Překlad C++ kódu do Delphi (6,7)
« Odpověď #6 kdy: 13-04-2015, 15:15:01 »
Snažím se prokousat C++ kódem a momentálně jsem uvízl ve funkci getDraw (začínající od řádku 187). Mohl by mi někdo poradit, kde a čím mám naplnit proměnné x a y? Našel jsem pouze jejich deklaraci v Spline.h: double x[128],y[128];.


Jinak takto jsem prozatím přepsal C++ kód do Delphi. Procedura MatrixSolve je vnořená.

Kód: Delphi [Vybrat]
  1.        
  2.         Procedure XXYYZZ;
  3.         var
  4.           Spline_Fit_body : array of T_XY_Bod;
  5.           AMag, AMagOld : single;
  6.           Ax, Ay, Bx, By, Cx, Cy, k : array of single;
  7.           Mat : array of array of single;
  8.  
  9.           procedure MatrixSolve(out B : array of single);
  10.           var  
  11.             i, j : integer;
  12.             Work : array of single;
  13.             WorkB : array of single;        
  14.           begin
  15.             SetLength(Work, length(Spline_Fit_body)-1);
  16.             SetLength(WorkB, length(Spline_Fit_body)-1);
  17.        
  18.             for i := 0 to length(Spline_Fit_body)-1 do
  19.             begin
  20.               Work[i] := B[i] / Mat[1, i];
  21.               WorkB[i] := Work[i];
  22.             end;
  23.  
  24.             for j := 0 to 9 do
  25.             begin
  26.               Work[0] := (B[0]-Mat[2, 0]*WorkB[1])/Mat[1, 0];
  27.               for i := 1 to length(Spline_Fit_body)-1 do
  28.                 Work[i] := (B[i]-Mat[0, i]*WorkB[i-1]-Mat[2, i]*WorkB[i+1])/Mat[1, i];
  29.               Work[length(Spline_Fit_body)-1] := (B[length(Spline_Fit_body)-1]-Mat[0, length(Spline_Fit_body)-1]*Work[length(Spline_Fit_body)-2])/Mat[1, length(Spline_Fit_body)-1];  
  30.  
  31.               for i := 0 to length(Spline_Fit_body)-1 do
  32.                 WorkB[i] := Work[i];
  33.             end;
  34.  
  35.             for i := 0 to length(Spline_Fit_body)-1 do
  36.               B[i] := Work[i];
  37.           end;
  38.  
  39.         {
  40.         .
  41.         .
  42.           zde je cyklus který projde DXF soubor a vytáhne všechny fit body splajny a uloží do pole Spline_Fit_body
  43.         .
  44.         .
  45.         }
  46.  
  47.         // má splajna nějaké Fit body? Pokud ano, můžeme ji začít řešit
  48.         if length(Spline_Fit_body) > 0 then
  49.         begin
  50.                
  51.           // vector A
  52.           SetLength(Ax, 0);
  53.           SetLength(Ay, 0);
  54.  
  55.           for i := 0 to length(Spline_Fit_body) - 2 do
  56.           begin
  57.             SetLength(Ax, length(Ax)+1);
  58.             SetLength(Ay, length(Ay)+1);
  59.             Ax[length(Ax)-1] := Spline_Fit_body[i+1].X - Spline_Fit_body[i].X;
  60.             Ay[length(Ay)-1] := Spline_Fit_body[i+1].Y - Spline_Fit_body[i].Y;            
  61.           end;
  62.  
  63.           // k
  64.           SetLength(k, 0);
  65.  
  66.           AMagOld := sqrt(Ax[0]*Ax[0] + Ay[0]*Ay[0]);
  67.           for i := 0 to length(Spline_Fit_body) - 3 do
  68.           begin
  69.             AMag := sqrt(Ax[i+1]*Ax[i+1] + Ay[i+1]*Ay[i+1]);
  70.             SetLength(k, length(k)+1);
  71.             k[length(k)-1] := AMagOld / AMag;
  72.             AMagOld := AMag;
  73.           end;
  74.           SetLength(k, length(k)+1);
  75.           k[length(k)-1] := 1.0;
  76.  
  77.           // Matrix
  78.           SetLength(Mat, 3);
  79.           for i := low(Mat) to high(Mat) do
  80.             SetLength(Mat[i], length(Spline_Fit_body));
  81.          
  82.           for i := 1 to length(Spline_Fit_body) - 2 do
  83.           begin
  84.             Mat[0, i] := 1.0;
  85.             Mat[1, i] := 2.0*k[i-1]*(1.0 + k[i-1]);
  86.             Mat[2, i] := k[i-1]*k[i-1]*k[i];
  87.           end;
  88.           Mat[1, 0] := 2.0;
  89.           Mat[2, 0] := k[0];
  90.           Mat[0, length(Spline_Fit_body)-1] := 1.0;
  91.           Mat[1, length(Spline_Fit_body)-1] := 2.0*k[length(Spline_Fit_body)-2];
  92.  
  93.           // vector B
  94.           SetLength(Bx, 1);
  95.           SetLength(By, 1);
  96.           Bx[length(Bx)-1] := 3.0*Ax[0];
  97.           By[length(By)-1] := 3.0*Ay[0];
  98.  
  99.           for i := 1 to length(Spline_Fit_body) - 2 do
  100.           begin
  101.             SetLength(Bx, length(Bx)+1);
  102.             SetLength(By, length(By)+1);
  103.             Bx[length(Bx)-1] := 3.0*(Ax[i-1] + k[i-1]*k[i-1]*Ax[i]);
  104.             By[length(By)-1] := 3.0*(Ay[i-1] + k[i-1]*k[i-1]*Ay[i]);
  105.           end;
  106.           SetLength(Bx, length(Bx)+1);
  107.           SetLength(By, length(By)+1);
  108.           Bx[length(Bx)-1] := 3.0*Ax[length(Spline_Fit_body)-2];
  109.           By[length(By)-1] := 3.0*Ay[length(Spline_Fit_body)-2];
  110.          
  111.           // vector C
  112.           MatrixSolve(Bx);
  113.           MatrixSolve(By);          
  114.  
  115.           SetLength(Cx, 0);
  116.           SetLength(Cy, 0);
  117.          
  118.           for i := 0 to length(Spline_Fit_body) - 2 do
  119.           begin
  120.             SetLength(Cx, length(Cx)+1);
  121.             SetLength(Cy, length(Cy)+1);
  122.             Cx[length(Cx)-1] := k[i]*Bx[i+1];
  123.             Cy[length(Cy)-1] := k[i]*By[i+1];            
  124.           end;
  125.  
  126.  
  127.           // TODO: kreslení (interpolace bodů) splajny
  128.  
  129.  
  130.         end;
« Poslední změna: 14-04-2015, 13:33:26 od age.new »

Offline Mi.Chal.

  • Guru
  • *****
  • Příspěvků: 574
  • Karma: 25
Re:Překlad C++ kódu do Delphi (6,7)
« Odpověď #7 kdy: 13-04-2015, 15:41:48 »
EDIT: už mi to došlo ... je to něco jako vícerozměrné pole (array of array of single)

Díky za rady. Zkusím to nějak sepsat do verze D6. Jen mi jetě není jasné co s:
vector< vector<float> >Mat( 3, vector<float>(m_FitPointCount) );

Díky


do závorky se takhle píší parametry konstruktoru, význam najdeš třeba na http://www.cplusplus.com/reference/vector/vector/vector/. Ta trojka bude počet prvků, to druhý asi iniciální hodnota

Offline pepak

  • Guru
  • *****
  • Příspěvků: 1326
  • Karma: 30
    • Pepak.net
Re:Překlad C++ kódu do Delphi (6,7)
« Odpověď #8 kdy: 14-04-2015, 08:18:44 »
Delphi už by měly umět generika taky, viz třeba http://docwiki.embarcadero.com/CodeExamples/XE7/en/Generics_Collections_TList_%28Delphi%29, takže by mělo jít TList<float>
Jo, ale chce to pro D6,7.

Offline age.new

  • Plnoletý
  • ***
  • Příspěvků: 115
  • Karma: 0
Re:Překlad C++ kódu do Delphi (6,7)
« Odpověď #9 kdy: 14-04-2015, 13:35:10 »
Tak jsem dokončil přepsání C++ kódu a na výstupu je skutečně správná křivka. Bohužel z nějakého důvodu Delphi "čas od času" zahlásí Access Violation při SelLength dynamického pole a s tím se bohužel nedá nic dělat. Ale kdyby si to někdo chtěl zprogramovat, tak to "občas" funguje.

Offline Mi.Chal.

  • Guru
  • *****
  • Příspěvků: 574
  • Karma: 25
Re:Překlad C++ kódu do Delphi (6,7)
« Odpověď #10 kdy: 14-04-2015, 14:39:00 »
Tak jsem dokončil přepsání C++ kódu a na výstupu je skutečně správná křivka. Bohužel z nějakého důvodu Delphi "čas od času" zahlásí Access Violation při SelLength dynamického pole a s tím se bohužel nedá nic dělat. Ale kdyby si to někdo chtěl zprogramovat, tak to "občas" funguje.

nejspíš si někde přepisuješ paměť a pak se to "někdy chová divně". Druhá možnost je víc vláken bez odpovídající synchronizace, ale to asi nemáš.

Offline age.new

  • Plnoletý
  • ***
  • Příspěvků: 115
  • Karma: 0
Re:Překlad C++ kódu do Delphi (6,7)
« Odpověď #11 kdy: 14-04-2015, 14:57:32 »
Zapnul jsem všechny dostupné debugy a našel jsem některé Out of Range chyby, které pak ve spolupráci s SetLength nějakým způsobem zbořili FastMM. Po jejich odstranění to nedělá.

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 3404
  • Karma: 35
    • Verze Delphi: XE7 professional
Re:Překlad C++ kódu do Delphi (6,7)
« Odpověď #12 kdy: 14-04-2015, 15:49:15 »
Hm, to nemáš zapnutú kontrolu rozsahu?
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

 

S rychlou odpovědí můžete používat BB kódy a emotikony jako v běžném okně pro odpověď, ale daleko rychleji.

Upozornění: do tohoto tématu bylo naposledy přispěno před 120 dny.
Zvažte prosím založení nového tématu.

Jméno: E-mail:
Ověření:
Datový typ v Delphi, který má True a False: