Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Fr Jul 18, 2025 18:31

Foren-Übersicht » English » English Programming Forum
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 3 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: usefull???
BeitragVerfasst: Mi Apr 07, 2004 18:19 
Offline
DGL Member
Benutzeravatar

Registriert: Di Jul 01, 2003 18:59
Beiträge: 887
Wohnort: (The Netherlands)
Programmiersprache: fpc/delphi/java/c#
Sometimes you have to do things differently, like making a vector an object.

Let me know what you think.

Code:
  1.  
  2. {*******************************************************}
  3. {                                                       }
  4. {                Vector Object Library                  }
  5. {                                                       }
  6. {              Copyright (c) 2004 Noeska                }
  7. {                                                       }
  8. {*******************************************************}
  9.  
  10. unit glVector;
  11.  
  12. interface
  13.  
  14. uses classes, windows;
  15.  
  16. type
  17.   TRandomFunc = (rNegoneToOne, rZeroToOne); // (-1..1) (0..1)
  18.  
  19.   TVector3D = class(TObject)
  20.   private
  21.     Fx: single;
  22.     Fy: single;
  23.     Fz: single;
  24.     function  GetNormalized: TVector3d; //same as above but return a new vector
  25.     function  GetLength: single; //returns the length of a vector
  26.   protected
  27.   public
  28.     constructor Create; reintroduce; overload;
  29.     constructor Create(vx,vy,vz: single); reintroduce; overload;
  30.     destructor Destroy; reintroduce;
  31.     property x: single read Fx write Fx;
  32.     property y: single read Fy write Fy;
  33.     property z: single read Fz write Fz;
  34.     procedure Assign(v: TVector3D); reintroduce; //set x,y,z from other vector
  35.     procedure Add(v: TVector3D); //Addition
  36.     procedure Sub(v: TVector3D); //Subtraction
  37.     procedure Mul(value: single); //Scale by Multiplication
  38.     procedure Divide(value: single); //Scale by Division
  39.     function  Dot(v: TVector3D): single; //Dot product (angle between 2 vectors)
  40.     function  Cross(v: TVector3D): TVector3D; //Cross product (perpendicular vector)
  41.     procedure Negative; //flips positive and negative
  42.     procedure Normalize; //make the vector have a length of 1 but keep direction
  43.     property  Normalized: TVector3D read GetNormalized; //as above but returns a new vector
  44.     property  Length: single read GetLength; //length of vector
  45.     property  Magnitude: single read GetLength; //length of vector
  46.     procedure Rand(value: TRandomFunc); //fills vector  with random values
  47.   end;
  48.  
  49. implementation
  50.  
  51.   constructor TVector3D.Create;
  52.   begin
  53.     inherited Create();
  54.     Fx:=0.0;
  55.     Fy:=0.0;
  56.     Fz:=0.0;
  57.   end;
  58.  
  59.   constructor TVector3D.Create(vx,vy,vz: single);
  60.   begin
  61.     inherited Create();
  62.     Fx:=vx;
  63.     Fy:=vy;
  64.     Fz:=vz;
  65.   end;
  66.  
  67.   destructor TVector3D.Destroy;
  68.   begin
  69.     if normalized <> nil then normalized.free; //free's the normalized property if not done from application
  70.     inherited Destroy();
  71.   end;
  72.  
  73.   procedure TVector3D.Assign(v: TVector3D);
  74.   begin
  75.     Fx:=v.x;
  76.     Fy:=v.y;
  77.     Fz:=v.z;
  78.   end;
  79.  
  80.   procedure TVector3D.Add(v: TVector3D);
  81.   begin
  82.     Fx:=Fx+v.x;
  83.     Fy:=Fy+v.y;
  84.     Fz:=Fz+v.z;
  85.   end;
  86.  
  87.   procedure TVector3D.Sub(v: TVector3D);
  88.   begin
  89.     Fx:=Fx-v.x;
  90.     Fy:=Fy-v.y;
  91.     Fz:=Fz-v.z;
  92.   end;
  93.  
  94.   procedure TVector3D.Mul(value: single);
  95.   begin
  96.     Fx:=Fx*value;
  97.     Fy:=Fy*value;
  98.     Fz:=Fz*value;
  99.   end;
  100.  
  101.   procedure TVector3D.Divide(value: single);
  102.   begin
  103.     Fx:=Fx/value;
  104.     Fy:=Fy/value;
  105.     Fz:=Fz/value;
  106.   end;
  107.  
  108.   function TVector3D.Dot(v: TVector3D): single;
  109.   begin
  110.     result:= Fx*v.x+Fy*v.y+Fz*v.z;
  111.   end;
  112.  
  113.   function TVector3D.Cross(v: TVector3D): TVector3D;
  114.   begin
  115.     result:= TVector3D.Create();
  116.     result.x:= Fy*v.z-Fz*v.y;
  117.     result.y:= Fz*v.x-Fx*v.z;
  118.     result.z:= Fx*v.y-Fy*v.x;
  119.   end;
  120.  
  121.   procedure TVector3D.Negative;
  122.   begin
  123.     Fx:=-Fx;
  124.     Fy:=-Fy;
  125.     Fz:=-Fz;
  126.   end;
  127.  
  128.   function TVector3D.GetLength: single;
  129.   begin
  130.     result := sqrt(Fx*Fx + Fy*Fy + Fz*Fz);
  131.   end;
  132.  
  133.   procedure TVector3d.normalize;
  134.   var
  135.     tmplength: single;
  136.   begin
  137.     tmplength:=GetLength;
  138.     if tmplength <> 0 then
  139.     begin
  140.       Fx:=Fx / tmplength;
  141.       Fy:=Fy / tmplength;
  142.       Fz:=Fz / tmplength;
  143.     end;
  144.   end;
  145.  
  146.   function TVector3d.GetNormalized;
  147.   var
  148.     tmplength: single;
  149.   begin
  150.     result:=nil;
  151.     tmplength:=Length;
  152.     if tmplength <> 0 then
  153.     begin
  154.       if normalized <> nil then normalized.free; //free's the normalized property if not done from application
  155.       result:=TVector3d.Create();
  156.       result.x:=Fx / tmplength;
  157.       result.y:=Fy / tmplength;
  158.       result.z:=Fz / tmplength;
  159.     end;
  160.   end;
  161.  
  162.   function RandNegOneToOne: single;
  163.   begin
  164.     result := -1.0+(random / 16383.0);
  165.   end;
  166.  
  167.   function RandZeroToOne: single;
  168.   begin
  169.     result := (random / 32767.0);
  170.   end;
  171.  
  172.   procedure TVector3d.Rand(value: TRandomFunc);
  173.   begin
  174.     if value=rNegOneToOne then
  175.     begin
  176.       Fx:=RandNegOneToOne;
  177.       Fy:=RandNegOneToOne;
  178.       Fz:=RandNegOneToOne;
  179.       Normalize;
  180.     end;
  181.  
  182.     if value=rZeroToOne then
  183.     begin
  184.       Fx:=RandZeroToOne;
  185.       Fy:=RandZeroToOne;
  186.       Fz:=RandZeroToOne;
  187.       Normalize;
  188.     end;
  189.   end;
  190.  
  191. end.
  192.  


And an example:

Code:
  1.  
  2. program testvector;
  3. {$APPTYPE CONSOLE}
  4. uses
  5.   Classes,
  6.   SysUtils,
  7.   glVector;
  8.  
  9. type
  10.   //the old t3dpoint type
  11.   T3dpoint     = packed record
  12.     x, y, z        :Single;
  13.   end;
  14.   P3dpoint = ^T3dpoint;
  15.  
  16. const aantal= 99999;  //aantal is dutch for 'number of'
  17.  
  18. var
  19.   vectorlist, pointlist: tlist;
  20.   v3d1,v3d2 : tVector3D;
  21.   tmpcount: integer;
  22.   pointptr: P3dpoint;
  23.  
  24. begin
  25. vectorlist:=Tlist.Create;   //used for testing vectors
  26. //pointlist:=Tlist.Create;    //used for testing 3dpoints
  27.  
  28. for tmpcount:=0 to aantal do
  29. begin
  30. vectorlist.Add(TVector3D.Create());
  31. TVector3d(vectorlist.Items[tmpcount]).x:=tmpcount;
  32.  
  33. //new(pointptr);
  34. //pointptr.x:=0.0;
  35. //pointptr.y:=0.0;
  36. //pointptr.z:=0.0;
  37. //pointlist.Add(pointptr);
  38. //P3DPoint(pointlist.Items[tmpcount]).x:=tmpcount;
  39.  
  40. end;
  41.  
  42. v3d1:= TVector3D.Create();
  43. v3d2:= TVector3D.Create(2.0, 0.0, 9.0);
  44.  
  45. writeln(FloatToStr(v3d1.x)+'test tvector3d');
  46. //v3d2.x:=2.0;
  47. //v3d2.y:=0.0;
  48. //v3d2.z:=9.0;
  49. Randomize;
  50.  
  51. v3d1.Rand(rNegOneToOne);
  52. //v3d1.Add(v3d2);
  53. Writeln(FloatToStr(v3d1.x)+'x test tvector3d');
  54. Writeln(FloatToStr(v3d1.y)+'y test tvector3d');
  55. Writeln(FloatToStr(v3d1.z)+'z test tvector3d');
  56. Writeln(FloatToStr(v3d1.length)+'length test tvector3d');
  57. v3d1.Normalize;
  58. Writeln(FloatToStr(v3d1.length)+'length test tvector3d');
  59. v3d2.Assign(v3d1.Normalized);
  60. v3d1.Normalized.Free; //can be a memory leek if not done (how to solve?)
  61.  
  62. for tmpcount:=aantal downto 0 do
  63. begin
  64.   //writeln(floattostr(TVector3d(vectorlist.Items[tmpcount]).x),'test tvector3d');
  65.   TVector3d(vectorlist.Items[tmpcount]).Free;
  66.   vectorlist.Delete(tmpcount);
  67.  
  68.   //writeln(floattostr(P3dpoint(pointlist.Items[tmpcount]).x),'test tpoint3d');
  69.   //dispose(pointlist.Items[tmpcount]);
  70.   //pointlist.Delete(tmpcount);
  71. end;
  72.  
  73. v3d1.Free;
  74. v3d2.Free;
  75.  
  76. vectorlist.Free;
  77. //pointlist.Free;
  78.  
  79. end.
  80.  


PS: there may be potential memory leaks on passing a tvector3d and not freeing that one afterwards....

_________________
http://3das.noeska.com - create adventure games without programming


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Apr 08, 2004 09:10 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Dez 13, 2002 12:18
Beiträge: 1063
Looks ok to me - if you want to get really fancy, you could declare it as custom variant, and use operator overloading for it :wink:

However, since vector routines tend to be called quite often, I'd rather keep the data in records and use VectorXXX routines, since there is a bit of overhead by dereferencing the pointer to the object instance if you use a TVector3D, as well as a implicit "self" parameter in methods.

Besides: using your TVector3D data type, it would be quite difficult (if not to say impossible) to declare tables for vertex arrays or vbos.

_________________
Viel Spaß beim Programmieren,
Mars
http://www.basegraph.com/


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Apr 08, 2004 10:56 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Dez 28, 2002 11:13
Beiträge: 2244
I don't think that a reference type is the best solution for vertices, because it make copying data much more complicated. The new Delphi 8 for .Net allows methods and operators in records. The old TP objects are value types like records and also allow methods,but according to the Delphi Help they should not be used anymore.


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 3 Beiträge ] 
Foren-Übersicht » English » English Programming Forum


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 2 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.008s | 16 Queries | GZIP : On ]