📄 graphmath.pas
字号:
Result := not RE(a, b, Err) and (a < b);
end;
function RG(const a, b: Double; Err: Double = ERROR7): Boolean;
begin
Result := not RE(a, b, Err) and (a > b);
end;
function RLE(const a, b: Double; Err: Double = ERROR7): Boolean;
begin
Result := (a < b) or RE(a, b, Err);
end;
function RGE(const a, b: Double; Err: Double = ERROR7): Boolean;
begin
Result := (a > b) or RE(a, b, Err);
end;
{两变量是否相同}
function VarEqual(const A, B: Variant): Boolean;
begin
Result := (VarType(A) = VarType(B)) and (A = B);
end;
{两点是否相同}
function IsSamePoint(const x1, y1, x2, y2: Double; Err: Double = ERROR7): Boolean;
begin
Result := (Abs(x1 - x2) < Err) and (Abs(y1 - y2) < Err);
end;
function IsSamePoint(const Pnt1, Pnt2: TRealPoint; Err: Double = ERROR7): Boolean;
begin
Result := IsSamePoint(Pnt1.x, Pnt1.y, Pnt2.x, Pnt2.y, Err);
end;
{两边是否相同}
function IsSameEdge(const pEdge1, pEdge2: pPolygonEdge; Err: Double = ERROR7): Boolean;
begin
Result := True;
if (pEdge1.pPolyArc = nil) and (pEdge2.pPolyArc <> nil) or
(pEdge1.pPolyArc <> nil) and (pEdge2.pPolyArc = nil) then
Result := False
else
begin //同为弧或线段
if (not IsSamePoint(pEdge1.sPnt, pEdge2.sPnt, Err)) or (not IsSamePoint(pEdge1.ePnt, pEdge2.ePnt, Err)) then
Result := False;
if pEdge1.pPolyArc <> nil then
begin
if (pEdge1.pPolyArc.bOutFlag <> pEdge2.pPolyArc.bOutFlag) or
(not IsSamePoint(pEdge1.pPolyArc.OPnt, pEdge2.pPolyArc.OPnt, Err)) or
(not RE(pEdge1.pPolyArc.sAng, pEdge2.pPolyArc.sAng, Err)) or
(not RE(pEdge1.pPolyArc.eAng, pEdge2.pPolyArc.eAng, Err)) or
(not RE(pEdge1.pPolyArc.R, pEdge2.pPolyArc.R, Err)) then
Result := False;
end;
end;
end;
{两个多边形是否完全一样(重叠)}
function IsSamePolygon(const pPolygon1, pPolygon2: pPolygonRecord; Err: Double = ERROR7): Boolean;
var
pEdge1, pEdge2: pPolygonEdge;
FindSameEdge: Boolean;
begin
Result := False;
if (pPolygon1.EdgeCount <> pPolygon2.EdgeCount) or
(pPolygon1.bExistArc <> pPolygon2.bExistArc) then
exit;
pEdge1 := pPolygon1.pHeadEdge;
pEdge2 := pPolygon2.pHeadEdge;
//在pPolygon2找到和pPolygon1头边一样的边
FindSameEdge := False;
while pEdge2 <> nil do
begin
if IsSameEdge(pEdge1, pEdge2, Err) then
begin
FindSameEdge := True;
break;
end;
pEdge2 := pEdge2.pEdgeNext;
end;
if not FindSameEdge then
Exit;
//比较其余对应边是否一样
while (pEdge1.pEdgeNext <> nil) and (pEdge1.pEdgeNext <> pPolygon1.pHeadEdge) do
begin
pEdge1 := pEdge1.pEdgeNext;
if pEdge2.pEdgeNext = nil then
pEdge2 := pPolygon2.pHeadEdge
else
pEdge2 := pEdge2.pEdgeNext;
if not IsSameEdge(pEdge1, pEdge2, Err) then
Exit;
end;
Result := True;
end;
{一个角是否在另两个角之间; Ang, Ang1, Ang2 = [0..4*pi)}
function BetweenAngle(Ang, Ang1, Ang2: TRadian; Err: Double = ERROR7): Boolean;
begin
Ang := NormalRadian(Ang);
Ang1 := NormalRadian(Ang1);
Ang2 := NormalRadian(Ang2);
MinToMax(Ang1, Ang2);
Result := RGE(Ang, Ang1, Err) and RLE(Ang, Ang2, Err);
end;
{一值是否在另两值之间}
function BetweenValue(const Val, Val1, Val2: Double; Err: Double = ERROR7): Boolean;
begin
Result := RGE(Val, min(Val1, Val2), Err) and RLE(Val, max(Val1, Val2), Err);
end;
{判断点是否在直线上}
function PointOnLine(const x, y: Double; const BLine: TBeeLine; Err: Double = ERROR7): Boolean;
begin
Result := DisPointLine(x, y, BLine) < Err;
end;
function PointOnLine(const x, y: Double; const BLine: TSecLine; Err: Double = ERROR7): Boolean;
begin
Result := PointOnLine(x, y, BeeLine(BLine), Err);
end;
function PointOnLine(const Pnt, Pnt1, Pnt2: TRealPoint; Err: Double = ERROR7): Boolean; //点dPnt-直线(dPnt1dPnt2构成的)
begin
Result := PointOnLine(Pnt.x, Pnt.y, BeeLine(Pnt1, Pnt2), Err);
end;
function PointOnLine(const Pnt: TRealPoint; pEdge: pPolygonEdge; Err: Double = ERROR7): Boolean;
begin
Result := PointOnLine(Pnt, pEdge.sPnt, pEdge.ePnt, Err);
end;
{判断点是否在线段上}
function PointOnSeg(const x, y, x1, y1, x2, y2: Double; Err: Double = ERROR7): Boolean;
begin
Result := False;
if not PointOnLine(x, y, BeeLine(x1, y1, x2, y2), Err) then
Exit;
if BetweenValue(x, x1, x2, Err) and BetweenValue(y, y1, y2, Err) then
Result := True;
end;
function PointOnSeg(const x, y: Double; const lineS: TSecLine; Err: Double = ERROR7): Boolean;
begin
Result := PointOnSeg(x, y, lines.x1, lines.y1, lines.x2, lines.y2, Err);
end;
function PointOnSeg(const P: TRealPoint; const lineS: TSecLine; Err: Double = ERROR7): Boolean;
begin
Result := PointOnSeg(P.x, P.y, lineS, Err);
end;
function PointOnSeg(const dPnt, dPnt1, dPnt2: TRealPoint; Err: Double = ERROR7): Boolean;
var
ASecLine: TSecLine;
begin
ASecLine := SecLine(dPnt1, dPnt2);
Result := PointOnSeg(dPnt, ASecLine, Err);
end;
function PointOnSeg(const dPnt: TRealPoint; pEdge: pPolygonEdge; Err: Double = ERROR7): Boolean;
begin
Result := PointOnSeg(dPnt, pEdge.sPnt, pEdge.ePnt, Err);
end;
{判断点是否在弧线上}
function PointOnArc(const x, y, R: Double; const OPnt: TRealPoint; const sAng, eAng: TRadian; Err: Double = ERROR7): Boolean;
var
Dis: Double;
Ang, AngErr: TRadian; //统一角度和距离的误差
dPnt: TRealPoint;
begin
Result := False;
Dis := DisPointPoint(x, y, OPnt.x, OPnt.y);
if RE(Dis, R, Err) then
begin
dPnt.x := x;
dPnt.y := y;
Ang := LineAngle(OPnt, dPnt);
AngErr := Err / R;
if BetweenAngle(Ang, sAng, eAng, AngErr) then
Result := True;
end;
end;
function PointOnArc(x, y: Double; pArc: pPolygonArc; Err: Double = ERROR7): Boolean;
begin
Result := PointOnArc(x, y, pArc.R, PArc.OPnt, PArc.sAng, pArc.eAng, Err);
end;
function PointOnArc(dPnt: TRealPoint; pArc: pPolygonArc; Err: Double = ERROR7): Boolean;
begin
Result := PointOnArc(dPnt.x, dPnt.y, pArc, Err);
end;
function PointOnArc(x, y: Double; Arc: TCircleArc; Err: Double = ERROR7): Boolean; // 弧(圆心式)
begin
Result := PointOnArc(x, y, Arc.r, Arc.oPnt, Arc.sAng, Arc.eAng, Err);
end;
function PointOnArc(P: TRealPoint; arc: TCircleArc; Err: Double = ERROR7): Boolean;
begin
Result := PointOnArc(P.x, P.y, arc, Err);
end;
{判断一点是否在多边形某边上}
function PointOnEdge(const Pnt: TRealPoint; const pEdge: pPolygonEdge; Err: Double = ERROR7): Boolean;
begin
if pEdge.pPolyArc <> nil then
Result := PointOnArc(Pnt, pEdge.pPolyArc, Err)
else
Result := PointOnSeg(Pnt, pEdge, Err);
end;
{判断点是否在多边形的某边线上}
function PointOnPolygon(const APnt: TRealPoint; const pHeadEdge: pPolygonEdge; Err: Double = ERROR7): Boolean;
var
pEdge: pPolygonEdge;
IsOnRim: Boolean;
begin
Result := True;
pEdge := pHeadEdge;
while pEdge <> nil do
begin
IsOnRim := PointOnEdge(APnt, pEdge, Err);
if IsOnRim then
Exit;
pEdge := pEdge.pEdgeNext;
end;
Result := False;
end;
{判断线段p1p2是否在直线q1q2上}
function SegOnLine(const Pnt1, Pnt2, sPnt, ePnt: TRealPoint; Err: Double = ERROR7): Boolean;
begin
Result := PointOnLine(Pnt1, ePnt, ePnt, Err) and PointOnLine(Pnt2, sPnt, ePnt, Err);
end;
{判断线段pEdge是否在q1q2构成的直线上}
function SegOnLine(const pEdge: pPolygonEdge; const sPnt, ePnt: TRealPoint; Err: Double = ERROR7): Boolean;
begin
Result := SegOnLine(pEdge.sPnt, pEdge.ePnt, sPnt, ePnt, Err);
end;
{判断线段dPnt1dPnt2是否在线段dPnt3dPnt4上}
function SegOnSeg(const Pnt1, Pnt2, sPnt, ePnt: TRealPoint; Err: Double = ERROR7): Boolean;
begin
Result := PointOnSeg(Pnt1, sPnt, ePnt, Err) and PointOnSeg(Pnt2, sPnt, ePnt, Err);
end;
{判断线段L1是否在线段L2上}
function SegOnSeg(const pEdge1, pEdge2: pPolygonEdge; Err: Double = ERROR7): Boolean;
begin
Result := SegOnSeg(pEdge1.sPnt, pEdge1.ePnt, pEdge2.sPnt, pEdge2.ePnt, Err);
end;
{点是否在圆线附近(可认为圆被选中) }
function PointNearCircle(const x, y, Ox, Oy, r: Double; OffVal: Double): Boolean;
var
Dis: Double;
begin
Dis := DisPointPoint(Ox, Oy, x, y);
Result := RL(abs(Dis - r), OffVal);
end;
function PointNearArc(const x, y, Ox, Oy, x1, y1, x2, y2: Double; OffVal: Double): Boolean;
var
R: Double;
Ang1, Ang2, Ang: Double;
begin
Result := false;
R := DisPointPoint(x, y, Ox, Oy);
if not PointNearCircle(x, y, Ox, Oy, R, OffVal) then Exit;
Ang1 := LineAngle(Ox, Oy, x1, y1);
Ang2 := LineAngle(Ox, Oy, x2, y2);
Ang := LineAngle(Ox, Oy, x, y);
Result := BetweenAngle(Ang, Ang1, Ang2);
end;
//-------------判断~是否在某区域内--------------((
{点是否在圆内}
function InCircle(const x, y, ox, oy, R: Double; Err: Double = ERROR7): Boolean;
var
Dis: Double;
begin
Dis := DisPointPoint(ox, oy, x, y); //
Result := RLE(Dis, R, Err);
end;
{点是否在环内}
function InAnnular(const x, y: Double; const Sector: TAnnular; Err: Double = ERROR7): Boolean;
var
Dis: Double;
Ang: TRadian;
ox, oy: Double;
begin
Result := False;
ox := Sector.ox;
oy := Sector.oy;
Dis := Sqrt(Sqr(ox - x) + Sqr(oy - y));
if not RGE(Dis, Sector.r1, Err) or not RLE(Dis, Sector.r2, Err) then
Exit;
Ang := LineAngle(ox, oy, x, y);
with Sector do
begin
if BetweenAngle(Ang, sAng, eAng, Err) then
Result := True;
end;
end;
{点是否在三角形内}
function InTriangle(p, p1, p2, p3: TRealPoint): Boolean;
const
Err: TRadian = ERROR2; // 相近角度的0.5度
var
Ang1, Ang2, Ang3: TRadian; //计算角度Ang1(P1_P),Ang2(P2_P),Ang3(P3_P)
//三个角度有一个大于pi,则说明此点位于三角形(P1_P2_P3)外部
begin
Result := False;
Ang1 := LineAngle(P, P1);
Ang2 := LineAngle(P, P2);
Ang3 := LineAngle(P, P3);
// 将三个角度按大小对Ang1,Ang2,Ang3的赋值
if Ang1 > Ang2 then
Ang2 := Ang2 + 2 * pi;
if Ang1 > Ang3 then
Ang3 := Ang3 + 2 * pi;
if Ang2 > Ang3 then
SwapValue(Ang2, Ang3);
//判断角度是否大于pi,如是则表明此点在三角形外
if (Ang2 - Ang1) > pi + Err th
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -