Up \Display

{@abstract( TSurfase class)
author: Nikolai Shokhirev )
created: January 01, 2001)
last modified: may 05, 2003)
ŠNikolai V. Shokhirev, 2001-2003}
unit uSurface;
interface

uses
  uMatTypes, extctrls, classes, controls, Graphics;

const
  code: array[1..8,1..3] of TInt =
        ((0,0,0),(1,0,0),(0,1,0),(1,1,0),(0,0,1),(1,0,1),(0,1,1),(1,1,1));

type

  TZofXY = function(const x, y: TFloat): TFloat;

  TSurface = class(TPaintBox)
  public
    { Public declarations }
    constructor Create(aOwner: TComponent; aParent: TWinControl);
    destructor Destroy; override;
    procedure SetMinMax(xMin, xMax, yMin, yMax, zMin, zMax: TFloat);
    procedure SetDimensions(margin: TInt; ViewAngle: TFloat);
    procedure SetFunction(ZFunc: TZofXY);
    procedure GetOrder;
    procedure Clear;
    procedure Line(ix1,iy1,ix2,iy2: TInt);
    procedure SetFramePoints;
    procedure DrawSurface;
    procedure DrawFrame;
    property BrushColor: TColor read GetBrushColor write SetBrushColor;
    property PenColor: TColor read GetPenColor write SetPenColor;
    property LineColor: TColor read fLineColor write fLineColor;
    property FillColor: TColor read fFillColor write fFillColor;
    property Angle: TFloat read GetAngle write SetAngle;  // deg
    property NInterval: TInt read GetNInterval write SetNInterval;
  end;

implementation

{          Y
   +-------|-------+ Ly/2
   |       |       |
   |       |       |
   +-------+-------+- X
   |       |       |
   |       |       |
   +-------+-------+ -Ly/2
 -Lx/2            Lx/2

Internal real (natural) coordinates
xMin < x < xMax, yMin < y < yMax, zMin < z < zMax
  x = xMin + (xx/Lx+1/2)*(xMax-xMin)
  y = yMin + (yy/Lx+1/2)*(yMax-yMin)
  z = zMin + (zz/Lz+1/2)*(zMax-zMin)
Internal 'integer' (symmetric) coordinates
-Lx/2 < xx < Lx/2, -Ly/2 < yy < Ly/2, -Lz/2 < zz < Lz/2
  xx = Lx*(x-xMin)/(xMax-xMin) - Lx/2
  yy = Lx*(y-yMin)/(yMax-yMin) - Ly/2
  zz = Lz*(z-zMin)/(zMax-zMin) - Lz/2
Coordinates in Reference (non-rotated) frame
  xx' = xx*Cos(Angle)-yy*Sin(Angle)
  yy' = xx*Sin(Angle)+yy*Cos(Angle)
  zz' = zz
  xx =  xx'*Cos(Angle)+yy'*Sin(Angle)
  yy = -xx'*Sin(Angle)+yy'*Cos(Angle)
  zz =  zz'
External 'integer' coordinates. The origin is in the bottom-left corner.
The X-axis goes to the right, Z - up, Y - into the screen.
  X = Width/2 + xx'
  Y = yy'
  Z = Height/2 + zz'
Screen coordinates. The origin is in the top-left corner.
The iX-axis goes to the right, iY - down.
  iX = round(X)
  iY = round(Height - ( Z + Y*Sin(ViewAngle) ) )

  iX = round(Width/2 + xx')
  iY = round(Height/2 - ( zz' + yy'*Sin(ViewAngle) ) )

  xx =  xx'*Cos(Angle)+yy'*Sin(Angle)
  yy = -xx'*Sin(Angle)+yy'*Cos(Angle)
  x = xMin + (xx/Lx+1/2)*(xMax-xMin)
  y = yMin + (yy/Lx+1/2)*(yMax-yMin)
  z = f(x,y)

  zz' = Lz*(z-zMin)/(zMax-zMin) - Lz/2
  iX = round(Width/2 + xx')
  iY = round(Height/2 - ( zz' + yy'*Sin(ViewAngle) ) )
}
end.

Up \Display