home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / sibdemo3.zip / SAMPLES.DAT / SAMPLES / GEOM3D / VECTOR.PAS < prev   
Pascal/Delphi Source File  |  1997-04-06  |  13KB  |  403 lines

  1. UNIT Vector;
  2.  
  3. {**************************************************************************
  4.  *                                                                        *
  5.  *                                                                        *
  6.  *                                                                        *
  7.  * Demonstration of operator overloading in Sibyl                         *
  8.  *                                                                        *
  9.  *                                                                        *
  10.  **************************************************************************}
  11.  
  12. INTERFACE
  13.  
  14. USES SysUtils;
  15.  
  16. TYPE TStatus=(stOk,stError);
  17.  
  18. TYPE EVectorError=CLASS(Exception);
  19.  
  20. TYPE TVector=OBJECT
  21.         PRIVATE
  22.               Fx,Fy,Fz:Extended;
  23.               FStatus:TStatus;
  24.         PUBLIC
  25.               CONSTRUCTOR Create(CONST x,y,z:Extended);
  26.               CONSTRUCTOR Create2D(CONST x,y:Extended);
  27.               PROCEDURE Normalize;
  28.               FUNCTION Amount:Extended;
  29.               FUNCTION ToStr:STRING;
  30.         PUBLIC
  31.               PROPERTY x:Extended read Fx write Fx;
  32.               PROPERTY y:Extended read Fy write Fy;
  33.               PROPERTY z:Extended read Fz write Fz;
  34.               PROPERTY Status:TStatus read FStatus write FStatus;
  35.      END;
  36.  
  37.      TPoint=TVector;
  38.  
  39.      TLine=OBJECT
  40.         PRIVATE
  41.               FStartPoint:TPoint;
  42.               FDirection:TVector;
  43.               FStatus:TStatus;
  44.         PUBLIC
  45.               CONSTRUCTOR Create(CONST p1,p2:TPoint);
  46.               CONSTRUCTOR CreateFromDirection(CONST p1:TPoint;CONST Direction:TVector);
  47.               FUNCTION SmallestDistance(h:TLine):Extended;
  48.               FUNCTION Perpendicular(h:TLine):TVector;
  49.               FUNCTION ToStr:STRING;
  50.         PUBLIC
  51.               PROPERTY StartPoint:TPoint read FStartPoint write FStartPoint;
  52.               PROPERTY Direction:TVector read FDirection write FDirection;
  53.               PROPERTY Status:TStatus read FStatus write FStatus;
  54.      END;
  55.  
  56.      TPlain=OBJECT
  57.         PRIVATE
  58.               FBasePoint:TPoint;
  59.               FPerpendicular:TVector;
  60.               Direction1:TVector;
  61.               Direction2:TVector;
  62.               FConstant:Extended;
  63.               FStatus:TStatus;
  64.         PUBLIC
  65.               CONSTRUCTOR Create(CONST p1:TPoint;CONST Perpendicular:TVector);
  66.               CONSTRUCTOR CreateFromPerpendicularConst(CONST Perpendicular:TVector;CONST Constant:Extended);
  67.               CONSTRUCTOR CreateFrom3Points(CONST p1,p2,p3:TPoint);
  68.               CONSTRUCTOR CreateFromLinePoint(CONST g:TLine;CONST p:TPoint);
  69.               FUNCTION Distance(p:TPoint):Extended;
  70.               FUNCTION tostr:STRING;
  71.         PUBLIC
  72.               PROPERTY BasePoint:TPoint read FBasePoint write FBasePoint;
  73.               PROPERTY Perpendicular:TVector read FPerpendicular write FPerpendicular;
  74.               PROPERTY Constant:Extended read FConstant write FConstant;
  75.               PROPERTY Status:TStatus read FStatus write FStatus;
  76.      END;
  77.  
  78. CONST
  79.      TostrLen:LONGWORD=0;
  80.      TostrDigits:LONGWORD=6;
  81.  
  82. //Operator overloads for TVector
  83.  
  84. //a+b=(ax+bx,ay+by,az+bz)
  85. FUNCTION VectorAdd(CONST a,b:TVector):TVector;operator +;
  86. //a-b=(ax-bx.ay-by,az-bz)
  87. FUNCTION VectorSub(CONST a,b:TVector):TVector;operator -;
  88. //a*b=ax*bx+ay*by+az*bz
  89. FUNCTION VectorMul(CONST a,b:TVector):Extended;operator *;
  90. //a#b=(ay*bz-az*by,az*bx-ax*bz,ax*by-ay*bx)
  91. FUNCTION VectorCrossMul(CONST a,b:TVector):TVector;operator #;
  92. //-a=(-ax,-ay,-az)
  93. FUNCTION VectorNegate(CONST a:TVector):TVector;operator -;
  94. //c*a=(ax*c,ay*c,az*c)
  95. FUNCTION VectorScalarMul1(CONST c:Extended;CONST a:TVector):TVector;operator *;
  96. //a*c=c*a
  97. FUNCTION VectorScalarMul2(CONST a:TVector;CONST c:Extended):TVector;operator *;
  98. //a/c=(ax/c,ay/c,az/c)
  99. FUNCTION VectorScalarDiv(CONST a:TVector;CONST c:Extended):TVector;operator /;
  100.  
  101. //Operator overloads for TLine
  102.  
  103. //Intersection point of two lines
  104. FUNCTION LineIntersect(CONST g,h:TLine):TPoint;operator #;
  105.  
  106. //Operator overloads for TPlain
  107.  
  108. //Intersection Point of Line and Plain
  109. FUNCTION LinePlainIntersect(CONST g:TLine;CONST e:TPlain):TPoint;operator #;
  110. //Intersection Poinz of Plain and Line
  111. FUNCTION PlainLineIntersect(CONST e:TPlain;CONST g:TLine):TPoint;operator #;
  112. //Intersection Point of 2 plains
  113. FUNCTION PlainIntersect(CONST e1,e2:TPlain):TLine;operator #;
  114.  
  115.  
  116. IMPLEMENTATION
  117.  
  118. {****************************************************************************
  119.  *                                                                          +
  120.  *                                                                          *
  121.  * TVector                                                                  *
  122.  *                                                                          *
  123.  *                                                                          *
  124.  ****************************************************************************}
  125.  
  126. //Operator overloads
  127.  
  128. //a+b=(ax+bx,ay+by,az+bz)
  129. FUNCTION VectorAdd(CONST a,b:TVector):TVector;
  130. BEGIN
  131.      result.Create(a.x+b.x,a.y+b.y,a.z+b.z);
  132. END;
  133.  
  134. //a-b=(ax-bx.ay-by,az-bz)
  135. FUNCTION VectorSub(CONST a,b:TVector):TVector;
  136. BEGIN
  137.      result.Create(a.x-b.x,a.y-b.y,a.z-b.z);
  138. END;
  139.  
  140. //a*b=ax*bx+ay*by+az*bz
  141. FUNCTION VectorMul(CONST a,b:TVector):Extended;
  142. BEGIN
  143.      result:=a.x*b.x+a.y*b.y+a.z*b.z;
  144. END;
  145.  
  146. //a#b=(ay*bz-az*by,az*bx-ax*bz,ax*by-ay*bx)
  147. FUNCTION VectorCrossMul(CONST a,b:TVector):TVector;
  148. BEGIN
  149.      result.Create(a.y*b.z-a.z*b.y,a.z*b.x-a.x*b.z,a.x*b.y-a.y*b.x);
  150. END;
  151.  
  152. //-a=(-ax,-ay,-az)
  153. FUNCTION VectorNegate(CONST a:TVector):TVector;
  154. BEGIN
  155.      result.Create(-a.x,-a.y,-a.z);
  156. END;
  157.  
  158. //c*a=(ax*c,ay*c,az*c)
  159. FUNCTION VectorScalarMul1(CONST c:Extended;CONST a:TVector):TVector;
  160. BEGIN
  161.      result.Create(a.x*c,a.y*c,a.z*c);
  162. END;
  163.  
  164. //a*c=c*a
  165. FUNCTION VectorScalarMul2(CONST a:TVector;CONST c:Extended):TVector;
  166. BEGIN
  167.      result:=c*a;
  168. END;
  169.  
  170. //a/c=(ax/c,ay/c,az/c)
  171. FUNCTION VectorScalarDiv(CONST a:TVector;CONST c:Extended):TVector;
  172. BEGIN
  173.      result.Create(a.x/c,a.y/c,a.z/c);
  174. END;
  175.  
  176. CONSTRUCTOR TVector.Create(CONST x,y,z:Extended);
  177. BEGIN
  178.      SELF.x:=x;
  179.      SELF.y:=y;
  180.      SELF.z:=z;
  181.      Status:=stOk;
  182. END;
  183.  
  184. CONSTRUCTOR TVector.Create2D(CONST x,y:Extended);
  185. BEGIN
  186.      TVector.Create(x,y,0);
  187. END;
  188.  
  189. FUNCTION TVector.Amount:Extended;
  190. BEGIN
  191.      result:=sqrt(sqr(x)+sqr(y)+sqr(z));
  192. END;
  193.  
  194. PROCEDURE TVector.Normalize;
  195. VAR A:Extended;
  196. BEGIN
  197.      A:=Amount;
  198.      x:=x/A;
  199.      y:=y/A;
  200.      z:=z/A;
  201. END;
  202.  
  203. FUNCTION TVector.ToStr:STRING;
  204. BEGIN
  205.      result:='( '+System.ToStr(x:TostrLen:ToStrDigits)+', '+
  206.                   System.ToStr(y:TostrLen:TostrDigits)+', '+
  207.                   System.ToStr(z:TostrLen:TostrDigits)+' )';
  208. END;
  209.  
  210. {****************************************************************************
  211.  *                                                                          +
  212.  *                                                                          *
  213.  * TLine                                                                    *
  214.  *                                                                          *
  215.  *                                                                          *
  216.  ****************************************************************************}
  217.  
  218. //Operator overloads for TLine
  219.  
  220. //Intersection point of two lines
  221. FUNCTION LineIntersect(CONST g,h:TLine):TPoint;
  222. VAR n:TVector;
  223.     k,t:Extended;
  224. BEGIN
  225.      //Make cross product of direction vectors
  226.      n:=g.Direction#h.Direction;
  227.  
  228.      IF n.Amount=0 THEN //identical or parallel
  229.      BEGIN
  230.           result.Create(1E38,1E38,1E38);
  231.           result.Status:=stError;
  232.           RAISE EVectorError.Create('Lines have no intersection point');
  233.           exit;
  234.      END;
  235.  
  236.      k:=abs((h.StartPoint-g.StartPoint)*n);
  237.      IF k<>0 THEN  //lines don't cross (Smalles distance <>0)
  238.      BEGIN
  239.           result.Create(1E38,1E38,1E38);
  240.           result.Status:=stError;
  241.           RAISE EVectorError.Create('Lines have no intersection point');
  242.           exit;
  243.      END;
  244.  
  245.      //Parameter for intersection point
  246.      t:=(((g.StartPoint.y-h.StartPoint.y) * (h.Direction.x)) - ((g.StartPoint.x-h.StartPoint.x) * (h.Direction.y)))
  247.         / ((g.Direction.x*h.Direction.y) - (g.Direction.y*h.Direction.x));
  248.  
  249.      result:=g.StartPoint+t*g.Direction;
  250.      result.Status:=stOk;
  251. END;
  252.  
  253.  
  254. CONSTRUCTOR TLine.Create(CONST p1,p2:TPoint);
  255. VAR p1p2:TVector;
  256. BEGIN
  257.      p1p2:=p2-p1;
  258.      TLine.CreateFromDirection(p1,p1p2);
  259. END;
  260.  
  261. CONSTRUCTOR TLine.CreateFromDirection(CONST p1:TPoint;CONST Direction:TVector);
  262. BEGIN
  263.      StartPoint:=p1;
  264.      SELF.Direction:=Direction;
  265.      SELF.Direction.Normalize;
  266.      Status:=stOk;
  267. END;
  268.  
  269. FUNCTION TLine.SmallestDistance(h:TLine):Extended;
  270. VAR n:TVector;
  271. BEGIN
  272.      n:=Direction#h.Direction;
  273.      result:=abs((h.StartPoint-StartPoint)*n);
  274. END;
  275.  
  276. FUNCTION TLine.Perpendicular(h:TLine):TVector;
  277. BEGIN
  278.      result:=Direction#h.Direction;
  279. END;
  280.  
  281. FUNCTION TLine.ToStr:STRING;
  282. BEGIN
  283.      result:=StartPoint.tostr+' + t '+Direction.tostr;
  284. END;
  285.  
  286. {****************************************************************************
  287.  *                                                                          +
  288.  *                                                                          *
  289.  * TPlain                                                                   *
  290.  *                                                                          *
  291.  *                                                                          *
  292.  ****************************************************************************}
  293.  
  294. //Operator overloads for TPlain
  295.  
  296. //Intersection Point of Line and Plain
  297. FUNCTION LinePlainIntersect(CONST g:TLine;CONST e:TPlain):TPoint;
  298. BEGIN
  299.      result:=e#g;
  300. END;
  301.  
  302. //Intersection Point of Plain and Line
  303. FUNCTION PlainLineIntersect(CONST e:TPlain;CONST g:TLine):TPoint;
  304. VAR temp:Extended;
  305. BEGIN
  306.      //test scalar product
  307.      temp:=g.Direction*e.Perpendicular;
  308.      IF temp=0 THEN //identical or parallel
  309.      BEGIN
  310.           result.Create(0,0,0);
  311.           result.Status:=stError;
  312.           RAISE EVectorError.Create('Plane and line have no intersection point');
  313.           exit;
  314.      END;
  315.  
  316.      temp:=(e.Constant-g.StartPoint*e.Perpendicular)/temp;
  317.      result:=g.StartPoint+temp*g.Direction;
  318. END;
  319.  
  320. //Intersection Point of 2 plains
  321. FUNCTION PlainIntersect(CONST e1,e2:TPlain):TLine;
  322. VAR
  323.     S:TPoint;
  324.     n:TVector;
  325.     temp,temp1:Extended;
  326. BEGIN
  327.      //Make cross product of perpendicular vectors (direction of intersectionn line)
  328.      n:=e1.Perpendicular#e2.Perpendicular;
  329.  
  330.      IF n.Amount=0 THEN //identical or parallel
  331.      BEGIN
  332.           result.Create(e1.BasePoint,e1.BasePoint);
  333.           result.Status:=stError;
  334.           RAISE EVectorError.Create('Planes have no intersection line');
  335.           exit;
  336.      END;
  337.  
  338.      temp:=e1.Perpendicular*e2.Direction1;
  339.      temp1:=e1.Constant-e1.Perpendicular*e2.BasePoint;
  340.  
  341.      IF temp=0 THEN S:=e2.BasePoint+((temp1/(e1.Perpendicular*e2.Direction2))*e2.Direction2)
  342.      ELSE S:=e2.BasePoint+((temp1/temp)*e2.Direction1);
  343.  
  344.      result.CreateFromDirection(S,n);
  345. END;
  346.  
  347. CONSTRUCTOR TPlain.Create(CONST p1:TPoint;CONST Perpendicular:TVector);
  348. BEGIN
  349.      BasePoint:=p1;
  350.      SELF.Perpendicular:=Perpendicular;
  351.      SELF.Perpendicular.Normalize;
  352.      Constant:=BasePoint*SELF.Perpendicular;
  353.      IF ((SELF.Perpendicular.X=0)AND(SELF.Perpendicular.Y=0)) THEN Direction1.Create(1,0,0)
  354.      ELSE
  355.      BEGIN
  356.           Direction1.Create(-SELF.Perpendicular.Y,SELF.Perpendicular.X,0);
  357.           Direction1.Normalize;
  358.      END;
  359.      Direction2:=SELF.Perpendicular#Direction1;
  360.      Status:=stOk;
  361. END;
  362.  
  363. CONSTRUCTOR TPlain.CreateFromPerpendicularConst(CONST Perpendicular:TVector;CONST Constant:Extended);
  364. VAR p1:TPoint;
  365. BEGIN
  366.      IF Perpendicular.z<>0 THEN p1.Create(0,0,Constant/Perpendicular.Z)
  367.      ELSE IF Perpendicular.y<>0 THEN p1.Create(0,Constant/Perpendicular.Y,0)
  368.      ELSE IF Perpendicular.x<>0 THEN p1.Create(Constant/Perpendicular.X,0,0)
  369.      ELSE
  370.      BEGIN
  371.           Status:=stError;
  372.           RAISE EVectorError.Create('Invalid plane definition');
  373.           exit;
  374.      END;
  375.      TPlain.Create(p1,Perpendicular);
  376. END;
  377.  
  378. CONSTRUCTOR TPlain.CreateFrom3Points(CONST p1,p2,p3:TPoint);
  379. VAR n:TVector;
  380. BEGIN
  381.      n:=(p2-p1)#(p3-p1);
  382.      TPlain.Create(p1,n);
  383. END;
  384.  
  385. CONSTRUCTOR TPlain.CreateFromLinePoint(CONST g:TLine;CONST p:TPoint);
  386. VAR p3:TPoint;
  387. BEGIN
  388.      p3:=g.StartPoint+g.Direction;
  389.      TPlain.CreateFrom3Points(p,g.StartPoint,p3);
  390. END;
  391.  
  392. FUNCTION TPlain.Distance(p:TPoint):Extended;
  393. BEGIN
  394.      result:=BasePoint*Perpendicular-Constant;
  395. END;
  396.  
  397. FUNCTION TPlain.tostr:STRING;
  398. BEGIN
  399.      result:=Perpendicular.tostr+' * '+BasePoint.tostr+' = '+System.tostr(Constant:TostrLen:TostrDigits);
  400. END;
  401.  
  402. END.
  403.