procedure MoveCursorToPosition(ACtrl:TControl;Pt:TPoint); begin if ACtrl<>nil then Pt:=ACtrl.ClientToScreen(Pt); SetCursorPos(Pt.x,Pt.y); end;function GetRectClient(ARect:TRect):TPoint; begin Result:=Point((ARect.Left+ARect.Right) div 2, (ARect.Top+ARect.Bottom) div 2); end;procedure GetSquarePoints(cPt:TPoint;NumSides,Radius:Integer; FA:Extended;var Points:TArrayOfPoint); Var I, X, Y : Integer; A:Extended; Begin SetLength(Points,0); if NumSides>0 then begin A:=360/NumSides; SetLength(Points,NumSides); For I:=0 to NumSides-1 Do Begin X:=cPt.x+Round(Radius*Sin((FA+A*I)*Pi/180)); Y:=cPt.y-Round(Radius*Cos((FA+A*I)*Pi/180)); Points[I]:=Point(X,Y); End; end; End;function NormalizeRect (ARect: TRect): TRect; var tmp: Integer; begin if ARect.Bottom < ARect.Top then begin tmp := ARect.Bottom; ARect.Bottom := ARect.Top; ARect.Top := tmp; end; if ARect.Right < ARect.Left then begin tmp := ARect.Right; ARect.Right := ARect.Left; ARect.Left := tmp; end; Result := ARect; end;function MakeRect(Pt1 : TPoint; Pt2 : TPoint) : TRect; begin if pt1.x < pt2.x then begin Result.Left := pt1.x; Result.Right := pt2.x; end else begin Result.Left := pt2.x; Result.Right := pt1.x; end; if pt1.y < pt2.y then begin Result.Top := pt1.y; Result.Bottom := pt2.y; end else begin Result.Top := pt2.y; Result.Bottom := pt1.y; end; end; 这是我整理的图形操作函数,可能有一两个函数调用了其他的单元,那些暂时可以忽略!
type TPointFLoat = record X : Real; Y : Real; end;// subtract 1 vector from another function Subtract(AVec1, AVec2 : TPoint) : TPoint; begin Result.X := AVec1.X - AVec2.X; Result.Y := AVec1.Y - AVec2.Y; end;//判断线和线是否相交// function LinesCross(LineAP1, LineAP2, LineBP1, LineBP2 : TPoint) : boolean; Var diffLA, diffLB : TPoint; CompareA, CompareB : integer; begin Result := False; diffLA := Subtract(LineAP2, LineAP1); diffLB := Subtract(LineBP2, LineBP1); CompareA := diffLA.X*LineAP1.Y - diffLA.Y*LineAP1.X; CompareB := diffLB.X*LineBP1.Y - diffLB.Y*LineBP1.X; if ( ((diffLA.X*LineBP1.Y - diffLA.Y*LineBP1.X) < CompareA) xor ((diffLA.X*LineBP2.Y - diffLA.Y*LineBP2.X) < CompareA) ) and ( ((diffLB.X*LineAP1.Y - diffLB.Y*LineAP1.X) < CompareB) xor ((diffLB.X*LineAP2.Y - diffLB.Y*LineAP2.X) < CompareB) ) then Result := True; end;//取得线与线的交点// function LineIntersect(LineAP1, LineAP2, LineBP1, LineBP2 : TPoint) : TPointFloat; Var LDetLineA, LDetLineB, LDetDivInv : Real; LDiffLA, LDiffLB : TPoint; begin LDetLineA := LineAP1.X*LineAP2.Y - LineAP1.Y*LineAP2.X; LDetLineB := LineBP1.X*LineBP2.Y - LineBP1.Y*LineBP2.X; LDiffLA := Subtract(LineAP1, LineAP2); LDiffLB := Subtract(LineBP1, LineBP2); LDetDivInv := 1 / ((LDiffLA.X*LDiffLB.Y) - (LDiffLA.Y*LDiffLB.X)); Result.X := ((LDetLineA*LDiffLB.X) - (LDiffLA.X*LDetLineB)) * LDetDivInv; Result.Y := ((LDetLineA*LDiffLB.Y) - (LDiffLA.Y*LDetLineB)) * LDetDivInv; end;function Distance(XPos, YPos, X, Y: Real): Real; begin Result:=sqrt( Power(XPos-X,2)+Power(YPos-Y,2)); end;function PointInCircle(cPt:TPointFloat;r:real;Pt:TPointFloat):Boolean; begin Result:=Distance(Pt.x,Pt.y,cPt.x,cPt.y)<r; end;function PointInEllipse(cPt:TPoint;L,T,R,B:Integer):Boolean; var BtnEllipse : HRgn; begin BtnEllipse := CreateEllipticRgn(L,T,R,B); try Result := PtInRegion(BtnEllipse,cPt.x,cPt.y); finally DeleteObject(BtnEllipse); end; end;function LineCrossRect(Pt1,Pt2:TPoint;ARect:TRect):Boolean; var IsPt1InRect,IsPt2InRect:Boolean; begin IsPt1InRect:=PtInRect(ARect,Pt1); IsPt2InRect:=PtInRect(ARect,Pt2); if IsPt1InRect and IsPt2InRect then Result:=False else Result:=LinesCross(Pt1,Pt2,Point(ARect.Left,ARect.Top),Point(ARect.Right,ARect.Top)) or LinesCross(Pt1,Pt2,Point(ARect.Right,ARect.Top),Point(ARect.Right,ARect.Bottom)) or LinesCross(Pt1,Pt2,Point(ARect.Right,ARect.Bottom),Point(ARect.Left,ARect.Bottom)) or LinesCross(Pt1,Pt2,Point(ARect.Left,ARect.Bottom),Point(ARect.Left,ARect.Top)); end;function clipTest(const p,q:Extended;var u1,u2:Extended):Boolean; var r:Extended; begin Result:=True; if (p<0.0) then begin r:=q/p; if (r>u2) then Result:=False else if (r>u1) then u1:=r; end else if (P>0.0) then begin r:=q/p; if (r<u1) then Result:=False else if (r<u2) then u2:=r; end else begin if (q<0.0) then Result:=False; end; end;
function clipLine(ARect:TRect;Pt1,Pt2:TPoint;var IPt1,IPt2:TPoint):Boolean; var u1,u2,dx,dy:Extended; mPt1,mPt2:TPointFloat; begin Result:=False;
u1:=0.0; u2:=1.0; dx:=Pt2.x-Pt1.x; if clipTest(-dx,Pt1.x-ARect.Left,u1,u2) then if clipTest(dx,ARect.Right-Pt1.x,u1,u2) then begin dy:=Pt2.y-Pt1.y; if clipTest(-dy,Pt1.y-ARect.Top,u1,u2) then if clipTest(dy,ARect.Bottom-Pt1.y,u1,u2) then begin if (u2<1.0) then begin mPt2.x:=Pt1.x+u2*dx; mPt2.y:=Pt1.y+u2*dy; end; if (u1>0.0) then begin mPt1.x:=Pt1.x+u1*dx; mPt1.y:=Pt1.y+u1*dy; end; IPt1:=Point(Round(mPt1.x),Round(mPt1.y)); IPt2:=Point(Round(mPt2.x),Round(mPt2.y)); Result:=True; end; end; end;function clipRect(const Rect1,Rect2:TRect;var IRect:TRect):Boolean; var Points : TArrayOfPoint; begin Result:=False; SetLength(Points,4); Points[0]:=Point(Rect1.Left,Rect1.Top); Points[1]:=Point(Rect1.Right,Rect1.Top); Points[2]:=Point(Rect1.Right,Rect1.Bottom); Points[3]:=Point(Rect1.Left,Rect1.Bottom); ClipPolygon(Points,Rect2); if High(Points)-Low(Points)>0 then begin IRect.Left:=Points[0].x; IRect.Top:=Points[0].y; IRect.Right:=Points[2].x; IRect.Bottom:=Points[2].y; Result:=True; end; SetLength(Points,0); end;
比如说交,
是不是说两个或多个Polygon,只取他们相交的部分图形但你的两个Polygon是先后画出来的,你第一个Polygon画出来时已经显示出来了,
再画第二个,怎么取交呢。
你把你的要求说清楚些好吗,
请问高手该如何写呀?
如果你愿意,可以加我的QQ,让我思考几天。
QQ:68816088
http://www.jos.org.cn/1000-9825/14/845.pdf
begin
if ACtrl<>nil then
Pt:=ACtrl.ClientToScreen(Pt);
SetCursorPos(Pt.x,Pt.y);
end;function GetRectClient(ARect:TRect):TPoint;
begin
Result:=Point((ARect.Left+ARect.Right) div 2,
(ARect.Top+ARect.Bottom) div 2);
end;procedure GetSquarePoints(cPt:TPoint;NumSides,Radius:Integer;
FA:Extended;var Points:TArrayOfPoint);
Var
I, X, Y : Integer;
A:Extended;
Begin
SetLength(Points,0);
if NumSides>0 then
begin
A:=360/NumSides;
SetLength(Points,NumSides);
For I:=0 to NumSides-1 Do
Begin
X:=cPt.x+Round(Radius*Sin((FA+A*I)*Pi/180));
Y:=cPt.y-Round(Radius*Cos((FA+A*I)*Pi/180));
Points[I]:=Point(X,Y);
End;
end;
End;function NormalizeRect (ARect: TRect): TRect;
var
tmp: Integer;
begin
if ARect.Bottom < ARect.Top then
begin
tmp := ARect.Bottom;
ARect.Bottom := ARect.Top;
ARect.Top := tmp;
end;
if ARect.Right < ARect.Left then
begin
tmp := ARect.Right;
ARect.Right := ARect.Left;
ARect.Left := tmp;
end;
Result := ARect;
end;function MakeRect(Pt1 : TPoint;
Pt2 : TPoint) : TRect;
begin
if pt1.x < pt2.x then begin
Result.Left := pt1.x;
Result.Right := pt2.x;
end else begin
Result.Left := pt2.x;
Result.Right := pt1.x;
end;
if pt1.y < pt2.y then begin
Result.Top := pt1.y;
Result.Bottom := pt2.y;
end else begin
Result.Top := pt2.y;
Result.Bottom := pt1.y;
end;
end;
这是我整理的图形操作函数,可能有一两个函数调用了其他的单元,那些暂时可以忽略!
TPointFLoat = record
X : Real;
Y : Real;
end;// subtract 1 vector from another
function Subtract(AVec1, AVec2 : TPoint) : TPoint;
begin
Result.X := AVec1.X - AVec2.X;
Result.Y := AVec1.Y - AVec2.Y;
end;//判断线和线是否相交//
function LinesCross(LineAP1, LineAP2, LineBP1, LineBP2 : TPoint) : boolean;
Var
diffLA, diffLB : TPoint;
CompareA, CompareB : integer;
begin
Result := False;
diffLA := Subtract(LineAP2, LineAP1);
diffLB := Subtract(LineBP2, LineBP1);
CompareA := diffLA.X*LineAP1.Y - diffLA.Y*LineAP1.X;
CompareB := diffLB.X*LineBP1.Y - diffLB.Y*LineBP1.X;
if ( ((diffLA.X*LineBP1.Y - diffLA.Y*LineBP1.X) < CompareA) xor
((diffLA.X*LineBP2.Y - diffLA.Y*LineBP2.X) < CompareA) ) and
( ((diffLB.X*LineAP1.Y - diffLB.Y*LineAP1.X) < CompareB) xor
((diffLB.X*LineAP2.Y - diffLB.Y*LineAP2.X) < CompareB) ) then
Result := True;
end;//取得线与线的交点//
function LineIntersect(LineAP1, LineAP2, LineBP1, LineBP2 : TPoint) : TPointFloat;
Var
LDetLineA, LDetLineB, LDetDivInv : Real;
LDiffLA, LDiffLB : TPoint;
begin
LDetLineA := LineAP1.X*LineAP2.Y - LineAP1.Y*LineAP2.X;
LDetLineB := LineBP1.X*LineBP2.Y - LineBP1.Y*LineBP2.X;
LDiffLA := Subtract(LineAP1, LineAP2);
LDiffLB := Subtract(LineBP1, LineBP2);
LDetDivInv := 1 / ((LDiffLA.X*LDiffLB.Y) - (LDiffLA.Y*LDiffLB.X));
Result.X := ((LDetLineA*LDiffLB.X) - (LDiffLA.X*LDetLineB)) * LDetDivInv;
Result.Y := ((LDetLineA*LDiffLB.Y) - (LDiffLA.Y*LDetLineB)) * LDetDivInv;
end;function Distance(XPos, YPos, X, Y: Real): Real;
begin
Result:=sqrt(
Power(XPos-X,2)+Power(YPos-Y,2));
end;function PointInCircle(cPt:TPointFloat;r:real;Pt:TPointFloat):Boolean;
begin
Result:=Distance(Pt.x,Pt.y,cPt.x,cPt.y)<r;
end;function PointInEllipse(cPt:TPoint;L,T,R,B:Integer):Boolean;
var
BtnEllipse : HRgn;
begin
BtnEllipse := CreateEllipticRgn(L,T,R,B);
try
Result := PtInRegion(BtnEllipse,cPt.x,cPt.y);
finally
DeleteObject(BtnEllipse);
end;
end;function LineCrossRect(Pt1,Pt2:TPoint;ARect:TRect):Boolean;
var
IsPt1InRect,IsPt2InRect:Boolean;
begin
IsPt1InRect:=PtInRect(ARect,Pt1);
IsPt2InRect:=PtInRect(ARect,Pt2);
if IsPt1InRect and IsPt2InRect then
Result:=False
else
Result:=LinesCross(Pt1,Pt2,Point(ARect.Left,ARect.Top),Point(ARect.Right,ARect.Top)) or
LinesCross(Pt1,Pt2,Point(ARect.Right,ARect.Top),Point(ARect.Right,ARect.Bottom)) or
LinesCross(Pt1,Pt2,Point(ARect.Right,ARect.Bottom),Point(ARect.Left,ARect.Bottom)) or
LinesCross(Pt1,Pt2,Point(ARect.Left,ARect.Bottom),Point(ARect.Left,ARect.Top));
end;function clipTest(const p,q:Extended;var u1,u2:Extended):Boolean;
var
r:Extended;
begin
Result:=True;
if (p<0.0) then
begin
r:=q/p;
if (r>u2) then
Result:=False
else
if (r>u1) then
u1:=r;
end
else if (P>0.0) then
begin
r:=q/p;
if (r<u1) then
Result:=False
else if (r<u2) then
u2:=r;
end
else
begin
if (q<0.0) then
Result:=False;
end;
end;
var
u1,u2,dx,dy:Extended;
mPt1,mPt2:TPointFloat;
begin
Result:=False;
mPt1.x:=Pt1.x;
mPt1.y:=Pt1.y;
mPt2.x:=Pt2.x;
mPt2.y:=Pt2.y;
u1:=0.0;
u2:=1.0;
dx:=Pt2.x-Pt1.x;
if clipTest(-dx,Pt1.x-ARect.Left,u1,u2) then
if clipTest(dx,ARect.Right-Pt1.x,u1,u2) then
begin
dy:=Pt2.y-Pt1.y;
if clipTest(-dy,Pt1.y-ARect.Top,u1,u2) then
if clipTest(dy,ARect.Bottom-Pt1.y,u1,u2) then
begin
if (u2<1.0) then
begin
mPt2.x:=Pt1.x+u2*dx;
mPt2.y:=Pt1.y+u2*dy;
end;
if (u1>0.0) then
begin
mPt1.x:=Pt1.x+u1*dx;
mPt1.y:=Pt1.y+u1*dy;
end; IPt1:=Point(Round(mPt1.x),Round(mPt1.y));
IPt2:=Point(Round(mPt2.x),Round(mPt2.y)); Result:=True;
end;
end;
end;function clipRect(const Rect1,Rect2:TRect;var IRect:TRect):Boolean;
var
Points : TArrayOfPoint;
begin
Result:=False; SetLength(Points,4);
Points[0]:=Point(Rect1.Left,Rect1.Top);
Points[1]:=Point(Rect1.Right,Rect1.Top);
Points[2]:=Point(Rect1.Right,Rect1.Bottom);
Points[3]:=Point(Rect1.Left,Rect1.Bottom); ClipPolygon(Points,Rect2); if High(Points)-Low(Points)>0 then
begin
IRect.Left:=Points[0].x;
IRect.Top:=Points[0].y;
IRect.Right:=Points[2].x;
IRect.Bottom:=Points[2].y;
Result:=True;
end; SetLength(Points,0);
end;