⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dxf_util.pas

📁 一个比较完整的读写dxf文件的DELPHI程序
💻 PAS
字号:
///////////////////////////////////////////////////////////////////////////////
//                                                                           //
//                      Assorted routines for DXF project                    //
//                             ㎎ohn Biddiscombe                             //
//                      Rutherford Appleton Laboratory, UK                   //
//                           j.biddiscombe@rl.ac.uk                          //
//                       DXF code release 3.0 - July 1997                    //
//                                                                           //
///////////////////////////////////////////////////////////////////////////////
unit DXF_Utils;

interface

uses
  Math, SysUtils;

type
  Point3D = record
    x,y,z : double;
  end;

  Point2D = record
    x,y : Double;
  end;

  PPoint3D   = ^Point3D;
  ppointlist = ^pointlist;
  pointlist  = array[0..0] of Point3D;

const
  origin3D : Point3D = (x:0; y:0; z:0);
  WCS_X    : Point3D = (x:1; y:0; z:0);
  WCS_Y    : Point3D = (x:0; y:1; z:0);
  WCS_Z    : Point3D = (x:0; y:0; z:1);

type
  pMatrix = ^Matrix;
  pM      = pMatrix;
  Matrix = record
    val : array[0..3,0..3] of double;
  end;

const
  identity : Matrix = (val:((1,0,0,0),(0,1,0,0),(0,0,1,0),(0,0,0,1)));

///////////////////////////////////////////////////////////////////////////////
// General point 3D stuff
///////////////////////////////////////////////////////////////////////////////
function aPoint3D(a,b,c:double)       : Point3D;
function p1_eq_p2_3D(p1,p2:Point3D)   : boolean;
function p1_eq_p2_2D(p1,p2:Point3D)   : boolean;
function p1_minus_p2(p1,p2:Point3D)   : Point3D;
function p1_plus_p2 (p1,p2:Point3D)   : Point3D;
function normalize(p1:Point3D)        : Point3D;
function mag(p1:Point3D)              : double;
function dist3D(p1,p2:Point3D)        : double;
function dist2D(p1,p2:Point3D)        : double;
function sq_dist3D(p1,p2:Point3D)     : double;
function sq_dist2D(p1,p2:Point3D)     : double;
function sq_mag3D(p1:Point3D)         : double;
function p1_x_n(p1:Point3D; n:double) : Point3D;
function set_accuracy(factor:double; p:Point3D) : Point3D;
///////////////////////////////////////////////////////////////////////////////
// Vector 3D stuff
///////////////////////////////////////////////////////////////////////////////
function dot(p1,p2:Point3D)                     : double;
function cross(p1,p2:Point3D)                   : Point3D;
function angle(p1,p2,p3:Point3D; do_3D:boolean) : double;
///////////////////////////////////////////////////////////////////////////////
// Rotations for Insert/Block drawing
///////////////////////////////////////////////////////////////////////////////
function XRotateMatrix(cos_a,sin_a:double)      : Matrix;
function YRotateMatrix(cos_a,sin_a:double)      : Matrix;
function ZRotateMatrix(cos_a,sin_a:double)      : Matrix;
function ScaleMatrix(p:Point3D)                 : Matrix;
function TranslateMatrix(p:Point3D)             : Matrix;
function MatrixMultiply(matrix1,matrix2:Matrix) : Matrix;
function CreateTransformation(Ax,Ay,Az:Point3D) : Matrix;
function TransformPoint(TM:Matrix; p:Point3D) : Point3D;
function update_transformations(OCS_WCS,OCS:pMatrix) : pMatrix;
function RotationAxis(A:Point3D; angle:double) : Matrix;
///////////////////////////////////////////////////////////////////////////////
// Bounds
///////////////////////////////////////////////////////////////////////////////
procedure max_bound(var bounds:Point3D; point:Point3D);
procedure min_bound(var bounds:Point3D; point:Point3D);
function  dmin(a,b:double) : double;
function  dmax(a,b:double) : double;
function  imin(a,b:integer) : integer;
function  imax(a,b:integer) : integer;
///////////////////////////////////////////////////////////////////////////////
// Memory
///////////////////////////////////////////////////////////////////////////////
function  allocate_points(n:integer) : ppointlist;
procedure deallocate_points(var pts:ppointlist; n:integer);
function  allocate_matrix : pMatrix;
procedure deallocate_matrix(var m:pMatrix);
///////////////////////////////////////////////////////////////////////////////
// String
///////////////////////////////////////////////////////////////////////////////
function float_out(f:double)     : string;
function Point3DToStr(p:Point3D) : string;
function BoolToStr(b:boolean)    : string;

implementation

function aPoint3D(a,b,c:double) : Point3D;
begin
  result.x := a; result.y := b; result.z := c;
end;

function p1_eq_p2_3D(p1,p2:Point3D) : boolean;
begin
  result := (p1.x=p2.x) and (p1.y=p2.y) and (p1.z=p2.z);
end;

function p1_eq_p2_2D(p1,p2:Point3D) : boolean;
begin
  result := (p1.x=p2.x) and (p1.y=p2.y);
end;

function p1_minus_p2(p1,p2:Point3D) : Point3D;
begin
  result.x := p1.x-p2.x;
  result.y := p1.y-p2.y;
  result.z := p1.z-p2.z;
end;

function p1_plus_p2(p1,p2:Point3D) : Point3D;
begin
  result.x := p1.x+p2.x;
  result.y := p1.y+p2.y;
  result.z := p1.z+p2.z;
end;

function normalize(p1:Point3D) : Point3D;
var mag : double;
begin
  mag := Sqrt( sqr(p1.x) + sqr(p1.y) + sqr(p1.z) );
  result.x := p1.x/mag;
  result.y := p1.y/mag;
  result.z := p1.z/mag;
end;

function mag(p1:Point3D) : double;
begin
  with p1 do result := Sqrt( sqr(x) + sqr(y) + sqr(z) );
end;

function dist3D(p1,p2:Point3D) : double;
begin
  with p1_minus_p2(p2,p1) do result := Sqrt( sqr(x) + sqr(y) + sqr(z) );
end;

function dist2D(p1,p2:Point3D) : double;
begin
  with p1_minus_p2(p2,p1) do result := Sqrt( sqr(x) + sqr(y) );
end;

function sq_dist3D(p1,p2:Point3D) : double;
begin
  with p1_minus_p2(p2,p1) do result := sqr(x) + sqr(y) + sqr(z);
end;

function sq_dist2D(p1,p2:Point3D) : double;
begin
  with p1_minus_p2(p2,p1) do result := sqr(x) + sqr(y);
end;

function sq_mag3D(p1:Point3D) : double;
begin
  with p1 do result := sqr(x) + sqr(y) + sqr(z);
end;

function p1_x_n(p1:Point3D; n:double) : Point3D;
begin
  result.x := p1.x*n;
  result.y := p1.y*n;
  result.z := p1.z*n;
end;

function set_accuracy(factor:double; p:Point3D) : Point3D;
begin
  result.x := round(p.x*factor)/factor;
  result.y := round(p.y*factor)/factor;
  result.z := round(p.z*factor)/factor;
end;
///////////////////////////////////////////////////////////////////////////////
// Vector 3D stuff
///////////////////////////////////////////////////////////////////////////////
function dot(p1,p2:Point3D) : double;
begin
  result := p1.x*p2.x + p1.y*p2.y + p1.z*p2.z;
end;

function cross(p1,p2:Point3D) : Point3D;
begin
  result.x := p1.y*p2.z - p1.z*p2.y;
  result.y := p1.z*p2.x - p1.x*p2.z;
  result.z := p1.x*p2.y - p1.y*p2.x;
end;

function angle(p1,p2,p3:Point3D; do_3D:boolean) : double;
var v1,v2 : Point3D;
    d1,d2 : double;
begin
  v1 := p1_minus_p2(p2,p1);
  v2 := p1_minus_p2(p3,p2);
  if not do_3D then begin v1.z := 0; v2.z := 0; end;
  d1 := Mag(v1);
  d2 := Mag(v2);
  if ((d1=0) or (d2=0)) then result := 0
  else begin
    d1 := dot(v1,v2)/(d1*d2);
    if abs(d1)<=1 then result := ArcCos(d1)
    else result := 0;
  end;
end;
///////////////////////////////////////////////////////////////////////////////
// Rotations for Insert/Block drawing
///////////////////////////////////////////////////////////////////////////////
function XRotateMatrix(cos_a,sin_a:double) : Matrix;
begin
  result := identity;
  result.val[1,1]:= cos_a;   result.val[1,2]:=-sin_a;
  result.val[2,1]:= sin_a;   result.val[2,2]:= cos_a;
end;

function YRotateMatrix(cos_a,sin_a:double) : Matrix;
begin
  result := identity;
  result.val[0,0]:= cos_a;   result.val[0,2]:= sin_a;
  result.val[2,0]:=-sin_a;   result.val[2,2]:= cos_a;
end;

function ZRotateMatrix(cos_a,sin_a:double) : Matrix;
begin
  result := identity;
  result.val[0,0]:= cos_a;   result.val[0,1]:=-sin_a;
  result.val[1,0]:= sin_a;   result.val[1,1]:= cos_a;
end;

function ScaleMatrix(p:Point3D) : Matrix;
begin
  result := identity;
  result.val[0,0] := p.x;
  result.val[1,1] := p.y;
  result.val[2,2] := p.z;
end;

function TranslateMatrix(p:Point3D) : Matrix;
begin
  result := identity;
  result.val[3,0] := p.x;
  result.val[3,1] := p.y;
  result.val[3,2] := p.z;
end;

function MatrixMultiply(matrix1,matrix2:matrix) : Matrix;
var row,column : integer;
begin
  for row:=0 to 3 do begin
    for column:=0 to 3 do result.val[row,column]:=
      matrix1.val[row,0]*matrix2.val[0,column] + matrix1.val[row,1]*matrix2.val[1,column] +
      matrix1.val[row,2]*matrix2.val[2,column] + matrix1.val[row,3]*matrix2.val[3,column];
  end;
end;

var
  GlobalTempMatrix : Matrix;

function update_transformations(OCS_WCS,OCS:pMatrix) : pMatrix;
begin
  if OCS=nil then result := OCS_WCS
  else if OCS_WCS=nil then result := OCS
  else begin
    GlobalTempMatrix := MatrixMultiply(OCS_WCS^,OCS^);
    result := @GlobalTempMatrix;
  end;
end;

{ Matrix order : For reference

  start with a point at ( cos(30),sin(30),0 )
  rotate by 30 degrees - shifts point to (1,0,0)
  then translate by (10,0,0) shifts to (11,0,0)
  then rotate by -45 degrees goes to (7.77, 7.77 ,0) 7.77 = Sqrt(11^2 /2 )
  NOTE THE ORDER OF MATRIX OPERATIONS !

    test := aPoint3D( cos(degtorad(30)) , sin(degtorad(30)) , 0);
    mat  := ZRotateMatrix( cos(degtorad(30)) , sin(degtorad(30)) );
    mat  := MatrixMultiply( mat , TranslateMatrix(aPoint3D(10,0,0)) );
    mat  := MatrixMultiply( mat , ZRotateMatrix( cos(degtorad(-45)) , sin(degtorad(-45)) ) );
    test := TransformPoint(mat,test);
}

function CreateTransformation(Ax,Ay,Az:Point3D) : Matrix;
begin
  result := Identity;
  result.val[0,0] :=Ax.x;  result.val[1,0] :=Ay.x;  result.val[2,0] :=Az.x;
  result.val[0,1] :=Ax.y;  result.val[1,1] :=Ay.y;  result.val[2,1] :=Az.y;
  result.val[0,2] :=Ax.z;  result.val[1,2] :=Ay.z;  result.val[2,2] :=Az.z;
end;

function TransformPoint(TM:Matrix; p:Point3D) : Point3D;
begin
  with TM do begin
    result.x := p.x*val[0,0] + p.y*val[1,0] + p.z*val[2,0] + val[3,0];
    result.y := p.x*val[0,1] + p.y*val[1,1] + p.z*val[2,1] + val[3,1];
    result.z := p.x*val[0,2] + p.y*val[1,2] + p.z*val[2,2] + val[3,2];
  end;
end;

function RotationAxis(A:Point3D; angle:double) : Matrix;
var sin_a,cos_a : double;
begin
  result := Identity;
    sin_a := sin(angle);
    cos_a := cos(angle);
    result.val[0][0] := (A.x*A.x + (1. - A.x*A.x)*cos_a);
    result.val[1][0] := (A.x*A.y*(1. - cos_a) + A.z*sin_a);
    result.val[2][0] := (A.x*A.z*(1. - cos_a) - A.y*sin_a);

    result.val[0][1] := (A.x*A.y*(1. - cos_a) - A.z*sin_a);
    result.val[1][1] := (A.y*A.y + (1. - A.y*A.y)*cos_a);
    result.val[2][1] := (A.y*A.z*(1. - cos_a) + A.x*sin_a);

    result.val[0][2] := (A.x*A.z*(1. - cos_a) + A.y*sin_a);
    result.val[1][2] := (A.y*A.z*(1. - cos_a) - A.x*sin_a);
    result.val[2][2] := (A.z*A.z + (1. - A.z*A.z)*cos_a);
end;
///////////////////////////////////////////////////////////////////////////////
// Bounds
///////////////////////////////////////////////////////////////////////////////
procedure max_bound(var bounds:Point3D; point:Point3D);
begin
  if point.x>bounds.x then bounds.x := point.x;
  if point.y>bounds.y then bounds.y := point.y;
  if point.z>bounds.z then bounds.z := point.z;
end;

procedure min_bound(var bounds:Point3D; point:Point3D);
begin
  if point.x<bounds.x then bounds.x := point.x;
  if point.y<bounds.y then bounds.y := point.y;
  if point.z<bounds.z then bounds.z := point.z;
end;

function dmin(a,b:double) : double;
begin
  if a<b then result := a else result := b;
end;

function dmax(a,b:double) : double;
begin
  if a>b then result := a else result := b;
end;

function imax(a,b:integer) : integer;
begin
  if a>b then result :=a else result:=b;
end;

function imin(a,b:integer) : integer;
begin
  if a>b then result :=b else result:=a;
end;

///////////////////////////////////////////////////////////////////////////////
// Memory
///////////////////////////////////////////////////////////////////////////////
function allocate_points(n:integer) : ppointlist;
begin
  Getmem(result,n*SizeOf(Point3D));
end;

procedure deallocate_points(var pts:ppointlist; n:integer);
begin
  Freemem(pts,n*SizeOf(Point3D));
  pts := nil;
end;

function allocate_matrix : pMatrix;
begin
  Getmem(result,SizeOf(Matrix));
end;

procedure deallocate_matrix(var m:pMatrix);
begin
  Freemem(m,SizeOf(Matrix));
  m := nil;
end;
///////////////////////////////////////////////////////////////////////////////
// String
///////////////////////////////////////////////////////////////////////////////
function float_out(f:double) : string;
begin
  result := FloatToStrF(f,ffFixed,7,3);
  //result := FloatToStr(f);
end;

function Point3DToStr(p:Point3D) : string;
begin
  result := '(' + FloatToStrF(p.x,ffFixed,7,2) + ', ' +
                  FloatToStrF(p.y,ffFixed,7,2) + ', ' +
                  FloatToStrF(p.z,ffFixed,7,2) + ')';
end;

function BoolToStr(b:boolean) : string;
begin
  if b then result := 'TRUE'
  else result := 'FALSE';
end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -