📄 graphmath.pas
字号:
{**************************************************************}
{ }
{ 图形数学函数库, 提供非常有用的图形运算方法。 }
{ ( 过教学反复测试) }
{ }
{**************************************************************}
unit GraphMath;
interface
uses
Windows, SysUtils, Classes, Graphics, Math, Variants;
const
NULL_VALUE = MaxInt;
ERR_SLOPE = MaxInt; //不存在的斜率
InError: Double = 1.0E-7;
ERROR9 = 1.0E-9;
ERROR8 = 1.0E-8;
ERROR7 = 1.0E-7;
ERROR4 = 1.0E-4;
ERROR2 = 0.00872664625997; //0.5度对应的弧度值
PI34 = 3 * Pi / 4;
PI14 = pi / 4;
PI12 = pi / 2;
PI32 = 3 * pi / 2;
type
TObjectType = (otUnknown, otLine, otPolygon, otArc, otCircle, otRect, otText, otCross, otGroup);
TArcCase = (acPtSmall, acPtBig, acCSmall, acCBig, acNotCSmall, acNotCBig);
TMyPosition = (psUnknown, psLeft, psTop, psRight, psBottom);
TPointLinePos = (plUnknown, plOn, plLeft, plTop, plRight, plBottom);
{R1在R2的内部(rpIn); 1:相交(rpCross) 2:相离(rpOut) 3:重叠(rpOver) 4: R1包含R2(rpBein)}
TRectPosition = (rpUnknown, rpIn, rpBeIn, rpOver, rpCross, rpOut);
{多边形边的关系:不确定,部分重复,相交,相切,相离,一边端点在另一边上}
TDotPolyPos = (dpUnknown, dpOn, dpIn, dpOut);
TEdgeEdgePos = (eeUnknown, eePartRep, eeCross, eeCut, eeOff, eeFirstOnSec, eeSecOnFirst);
TEdgePolyPos = (epUnknown, epOutAdj, epInAdj, epCross, epIn, epOut);
TLongStr = string[32]; //长名称字符串
TShortStr = string[10]; //短名称字符串
TNameStr = string[20]; //图形名称字符串
{ 角度 }
TDegree = Double;
TRadian = Double;
{一元二次方程的根}
TEquationRadix = record
x1, x2: Double; //根值
RadixNum: ShortInt; //0:无根;1:1个根;2:2个根
end;
{ 坐标点}
pRealPoint = ^TRealPoint;
TRealPoint = record
x, y: Double;
end;
{ 交点 }
TCrossPoint = record
PointNum: ShortInt; //PointNum = 0:无交点;1:1个交点;2:2个交点
IsCutPoint: Boolean; //弧线、弧弧是否相切, 在返回的PointNum=1时才有意义
case Byte of
0: (x1, y1, x2, y2: Double); //第一交点, 第二交点
1: (P1, P2: TRealPoint);
end;
TRealLine = record
x1, y1, x2, y2: Double;
end;
{ 直线(斜截式)}
TBeeLine = record
k: Double; //斜率
b: Double; //截距
ExistK: Boolean; //是否有斜率(若无斜率,b=x)
end;
{ 线段(两点式)}
TSecLine = record
case Byte of
0: (x1, y1, x2, y2: Double);
1: (P1, P2: TRealPoint);
end;
{ 标准矩形 }
TRectangle = record
case Byte of
0: (Left, Top, Right, Bottom: Double);
1: (TopLeft, BottomRight: TRealPoint);
end;
TBox = record
minx, miny, maxx, maxy: double;
end;
TIntRect = record
case Byte of
0: (x1, y1, x2, y2, x3, y3, x4, y4: Integer); //Order Four Points?
1: (Point1, Point2, Point3, Point4: TPoint);
end;
{任意矩形}
TAnyRectangle = record
case Byte of
0: (x1, y1, x2, y2, x3, y3, x4, y4: Double); // 左上,右上,右下,左下
1: (Point1, Point2, Point3, Point4: TRealPoint);
end;
{ 圆}
TCircle = record
cx, cy: Double; //圆心
r: Double; //半径
end;
{ 弧线(三点式)}
TPointArc = record
case Byte of
0: (x1, y1, x2, y2, x3, y3: Double); //端点一,端点二,端点三
1: (P1, P2, P3: TRealPoint);
end;
{ 弧线(圆心式)}
TCircleArc = record
sAng, eAng: TRadian; //起始、终止角[0..2*pi)
R: Double; //半径
line: Double;
ClockWise: Boolean; //标记弧形的顺逆时针方向,为真表示为顺时针
case Integer of
0: (ox, oy, sx, sy, ex, ey: Double); //圆心坐标
1: (oPnt, sPnt, ePnt: TRealPoint);
end;
{ 环形 }
PAnnular = ^TAnnular;
TAnnular = record
ox, oy: Double; // 圆心点
sAng, eAng: Double; // 起始角,终止角
r1, r2: Double; // 内弧半径,外弧半径
end;
{ 边弧 }
pPolygonArc = ^TPolygonArc;
TPolygonArc = record
sAng, eAng: TRadian; //圆心角(Img顺,Math逆)[0..2pi);
R: Double; //弧半径
bOutFlag: Boolean; //凹凸
case Byte of
0: (Ox, Oy: Double); //弧圆心
1: (OPnt: TRealPoint);
end;
{ 边 }
PPolygonEdge = ^TPolygonEdge;
TPolygonEdge = record
pPolyArc: pPolygonArc; //弧域,nil表示非弧边
pEdgePrior: PPolygonEdge; //前一条边(缺省为nil,头结点的pEdgePrior指向尾结点)
pEdgeNext: PPolygonEdge; //多边形下一条边(缺省为nil)
pReserve: Pointer; //保留指针
Tag: Integer; //边附加标记
case Byte of
0: (sX, sY, eX, eY: Double); //边(包括弧边)的端点
1: (sPnt, ePnt: TRealPoint);
end;
{ 多边形 }
pPolygonRecord = ^TPolygonRecord;
TPolygonRecord = record
pHeadEdge: PPolygonEdge; //第一条边
EdgeCount: Integer; //边数
BoxRect: TRectangle; //外围矩形
bExistArc: Boolean; //是否存在弧边
pOther: Pointer; //保留的指针
Name: string[20]; //多边形名
end;
{ 矩形 }
pRectRecord = ^TRectRecord;
TRectRecord = record
Rect: TRectangle;
BoxRect: TRectangle; //外围矩形
LineWidth: Double; //线宽
Name: string[20];
end;
{ 弧形 }
pArcRecord = ^TArcRecord;
TArcRecord = record
pArcData: pPolygonArc;
BoxRect: TRectangle; //外围矩形
ArcWidth: Double; //弧宽
Name: string[20];
case Byte of
0: (sX, sY, eX, eY: Double); //边(包括弧边)的端点
1: (sPnt, ePnt: TRealPoint);
end;
{ 圆 }
pCircleRecord = ^TCircleRecord;
TCircleRecord = record
R: Double; //圆心半径
BoxRect: TRectangle; //外围矩形
LineWidth: Double; //弧宽
Name: string[20];
case Byte of
0: (oX, oY: Double);
1: (oPnt: TRealPoint);
end;
{ 线段 }
pLineRecord = ^TLineRecord;
TLineRecord = record
Line: TSecLine; //线段
BoxRect: TRectangle; //外围矩形
LineWidth: Double; //弧宽
Name: string[20];
end;
{ 文本 }
pTextRecord = ^TTextRecord;
TTextRecord = record
Text: string;
Color: TColor;
BkColor: TColor;
BoxRect: TRectangle;
Angle: Double;
Name: string;
end;
{ 图形对象 }
pObjRec = ^TObjRec;
TObjRec = record
shape: TObjectType;
pObj: Pointer;
BoxRect: TRectangle;
bVisible: Boolean;
bSelected: Boolean;
bDeleted: Boolean;
end;
{ 数组类型 }
TArr33 = array[1..3, 1..3] of Extended;
TArr1 = array[1..3] of Extended;
TListArray = array of TList;
TPointArray = array of TPoint;
TRealPointArray = array of TRealPoint;
//===========================基本计算方法=====================================================>>
{加法运算}
procedure Add(var x: Integer; n: Integer); overload;
procedure Add(var x: Double; n: Double); overload;
procedure Add(var s1: string; s2: string); overload;
{减法运算}
procedure Sub(var x: Integer; n: Integer); overload;
procedure Sub(var x: Double; n: Double); overload;
procedure Sub(var s1: string; s2: string); overload;
{矢量减}
function VectorMinus(const dPnt1, dPnt2: TRealPoint): TRealPoint;
{矢量叉积}
function VectorCrossMult(const dPnt1, dPnt2: TRealPoint; Err: Double = ERROR7): Double;
{交换值}
procedure SwapValue(var x1, x2: Double); OverLoad;
procedure SwapValue(var x1, x2: Integer); OverLoad;
procedure SwapValue(var d1, d2: TRealPoint); OverLoad;
procedure SwapValue(var L1, L2: TLineRecord); OverLoad;
procedure SwapValue(var p1, p2: pointer); OverLoad;
procedure SwapValue(var List: TList; I, J: Integer); OverLoad;
{排序}
procedure MaxToMin(var x1, x2: Double);
procedure MinToMax(var x1, x2: Double);
{最大最小值}
function MaxV(const x1, x2: Integer): Integer; OverLoad;
function MaxV(const x1, x2: Double): Double; OverLoad;
function MaxV(const x1, x2, x3: Integer): Integer; OverLoad;
function MaxV(const x1, x2, x3: Double): Double; OverLoad;
function MinV(const x1, x2: Integer): Integer; OverLoad;
function MinV(const x1, x2: Double): Double; OverLoad;
function MinV(const x1, x2, x3: Integer): Integer; OverLoad;
function MinV(const x1, x2, x3: Double): Double; OverLoad;
{矩阵乘积}
function MatrixMultiply(const T1, T2: TArr33): TArr33;
{计算一元二次方程的根}
function EquationRadix(a, b, c: Double): TEquationRadix;
{将角度调整到[0,2*pi)}
function NormalDegree(const Angle: TDegree): TDegree;
function NormalRadian(const Radian: TRadian): TRadian;
{求正弦,余弦}
function MyCos(Angle: TRadian): Double;
function MySin(Angle: TRadian): Double;
{点的数组排序(从小到大)}
procedure SortPointByX(var dPntsArr: TRealPointArray); //按照x坐标
procedure SortPointByY(var dPntsArr: TRealPointArray); //按照y坐标
procedure SortPoint(var dPntsArr: TRealPointArray); //如果X坐标不同,按X排序,否则按Y排序
procedure SortArcPoint(var dPntsArr: TRealPointArray; OPnt: TRealPoint; R: Double); //对弧上的一些点排序(按照弧度从小到大)
//==========================判断类===============================================================>>
{比较实数大小关系R:实数;E:等于;L:小于;G:大于;}
function RE(const a, b: Double; Err: Double = ERROR7): Boolean;
function RL(const a, b: Double; Err: Double = ERROR7): Boolean;
function RG(const a, b: Double; Err: Double = ERROR7): Boolean;
function RLE(const a, b: Double; Err: Double = ERROR7): Boolean;
function RGE(const a, b: Double; Err: Double = ERROR7): Boolean;
{两个变量是否相同}
function VarEqual(const A, B: Variant): Boolean;
{两点是否相同}
function IsSamePoint(const x1, y1, x2, y2: Double; Err: Double = ERROR7): Boolean; overload;
function IsSamePoint(const Pnt1, Pnt2: TRealPoint; Err: Double = ERROR7): Boolean; overload;
{两边是否相同数据}
function IsSameEdge(const pEdge1, pEdge2: pPolygonEdge; Err: Double = ERROR7): Boolean;
{两个多边形是否完全一样(重叠)}
function IsSamePolygon(const pPolygon1, pPolygon2: pPolygonRecord; Err: Double = ERROR7): Boolean;
{一个角是否在另两个角之间}
function BetweenAngle(Ang, Ang1, Ang2: TRadian; Err: Double = ERROR7): Boolean;
{一值是否在另两值之间}
function BetweenValue(const Val, Val1, Val2: Double; Err: Double = ERROR7): Boolean;
{点是否在直线上}
function PointOnLine(const x, y: Double; const BLine: TBeeLine; Err: Double = ERROR7): Boolean; overload;
function PointOnLine(const x, y: Double; const BLine: TSecLine; Err: Double = ERROR7): Boolean; overload;
function PointOnLine(const Pnt, Pnt1, Pnt2: TRealPoint; Err: Double = ERROR7): Boolean; overload;
function PointOnLine(const Pnt: TRealPoint; pEdge: pPolygonEdge; Err: Double = ERROR7): Boolean; overload;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -