Rev 1 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1 | Rev 4 | ||
---|---|---|---|
Line 3... | Line 3... | ||
3 | interface |
3 | interface |
4 | 4 | ||
5 | {$INCLUDE DelphiXcfg.inc} |
5 | {$INCLUDE DelphiXcfg.inc} |
6 | 6 | ||
7 | uses |
7 | uses |
8 | Windows, Messages, SysUtils, Classes, Controls, Forms, MMSystem, DirectX; |
8 | Windows, Messages, SysUtils, Classes, Controls, Forms, MMSystem, Graphics, {$IFDEF _DMO_}MultiMon,{$ENDIF} |
- | 9 | {$IfDef StandardDX} |
|
- | 10 | {$IfDef DX9} |
|
- | 11 | Direct3D, DirectInput, |
|
- | 12 | {$EndIf} |
|
- | 13 | DirectDraw, DirectSound; |
|
- | 14 | {$Else} |
|
- | 15 | DirectX; |
|
- | 16 | {$EndIf} |
|
9 | 17 | ||
10 | type |
18 | type |
11 | 19 | ||
12 | { EDirectDrawError } |
20 | { EDirectDrawError } |
13 | 21 | ||
Line 48... | Line 56... | ||
48 | public |
56 | public |
49 | constructor Create; |
57 | constructor Create; |
50 | property Drivers[Index: Integer]: TDirectXDriver read GetDriver; default; |
58 | property Drivers[Index: Integer]: TDirectXDriver read GetDriver; default; |
51 | end; |
59 | end; |
52 | 60 | ||
- | 61 | {$IFDEF _DMO_} |
|
- | 62 | { TDirectXDriverEx } |
|
- | 63 | ||
- | 64 | TDirectXDriverEx = class(TCollectionItem) |
|
- | 65 | private |
|
- | 66 | FGUID: PGUID; |
|
- | 67 | FGUID2: TGUID; |
|
- | 68 | FDescription: string; |
|
- | 69 | FDriverName: string; |
|
- | 70 | FMonitor: HMonitor; |
|
- | 71 | FMonitorInfo: TMonitorInfo; |
|
- | 72 | procedure SetGUID(Value: PGUID); |
|
- | 73 | function ConvertHMonitor(iMonitor: HMonitor): TMonitorInfo; |
|
- | 74 | function GetMonitorInfo: TMonitorInfo; |
|
- | 75 | function GetFlags: DWORD; |
|
- | 76 | function GetTempSpace: TRect; |
|
- | 77 | function GetWorkSpace: TRect; |
|
- | 78 | public |
|
- | 79 | property GUID: PGUID read FGUID write SetGUID; |
|
- | 80 | property Monitor: HMonitor read FMonitor write FMonitor; |
|
- | 81 | property MonitorInfo: TMonitorInfo read GetMonitorInfo; |
|
- | 82 | published |
|
- | 83 | property Description: string read FDescription write FDescription; |
|
- | 84 | property DriverName: string read FDriverName write FDriverName; |
|
- | 85 | property WorkSpace: TRect read GetWorkSpace; |
|
- | 86 | property TempSpace: TRect read GetTempSpace; |
|
- | 87 | property Flags: DWORD read GetFlags; |
|
- | 88 | end; |
|
- | 89 | ||
- | 90 | { TDirectXDriversEx } |
|
- | 91 | ||
- | 92 | TDirectXDriversEx = class(TCollection) |
|
- | 93 | private |
|
- | 94 | function GetDriver(Index: Integer): TDirectXDriverEx; |
|
- | 95 | public |
|
- | 96 | constructor Create; |
|
- | 97 | property Drivers[Index: Integer]: TDirectXDriverEx read GetDriver; default; |
|
- | 98 | end; |
|
- | 99 | {$ENDIF} |
|
- | 100 | ||
53 | { TDXForm } |
101 | { TDXForm } |
54 | 102 | ||
55 | TDXForm = class(TForm) |
103 | TDXForm = class(TForm) |
56 | private |
104 | private |
57 | FStoreWindow: Boolean; |
105 | FStoreWindow: Boolean; |
Line 168... | Line 216... | ||
168 | FHash: array[0..255] of THashCollectionItem; |
216 | FHash: array[0..255] of THashCollectionItem; |
169 | public |
217 | public |
170 | function IndexOf(const Name: string): Integer; |
218 | function IndexOf(const Name: string): Integer; |
171 | end; |
219 | end; |
172 | 220 | ||
- | 221 | {Addapted from RXLib.PicClip} |
|
- | 222 | ||
- | 223 | { TPicClip } |
|
- | 224 | TCellRange = 1..MaxInt; |
|
- | 225 | ||
- | 226 | TDXPictureClip = class(TComponent) |
|
- | 227 | private |
|
- | 228 | FPicture: TPicture; |
|
- | 229 | FRows: TCellRange; |
|
- | 230 | FCols: TCellRange; |
|
- | 231 | FBitmap: TBitmap; |
|
- | 232 | FMasked: Boolean; |
|
- | 233 | FMaskColor: TColor; |
|
- | 234 | FOnChange: TNotifyEvent; |
|
- | 235 | procedure CheckIndex(Index: Integer); |
|
- | 236 | function GetCell(Col, Row: Cardinal): TBitmap; |
|
- | 237 | function GetGraphicCell(Index: Integer): TBitmap; |
|
- | 238 | function GetDefaultMaskColor: TColor; |
|
- | 239 | function GetIsEmpty: Boolean; |
|
- | 240 | function GetCount: Integer; |
|
- | 241 | function GetHeight: Integer; |
|
- | 242 | function GetWidth: Integer; |
|
- | 243 | function IsMaskStored: Boolean; |
|
- | 244 | procedure PictureChanged(Sender: TObject); |
|
- | 245 | procedure SetHeight(Value: Integer); |
|
- | 246 | procedure SetPicture(Value: TPicture); |
|
- | 247 | procedure SetWidth(Value: Integer); |
|
- | 248 | procedure SetMaskColor(Value: TColor); |
|
- | 249 | protected |
|
- | 250 | procedure AssignTo(Dest: TPersistent); override; |
|
- | 251 | procedure Changed; dynamic; |
|
- | 252 | public |
|
- | 253 | constructor Create(AOwner: TComponent); override; |
|
- | 254 | destructor Destroy; override; |
|
- | 255 | procedure Assign(Source: TPersistent); override; |
|
- | 256 | function GetIndex(Col, Row: Cardinal): Integer; |
|
- | 257 | procedure Draw(Canvas: TCanvas; X, Y, Index: Integer); |
|
- | 258 | procedure DrawCenter(Canvas: TCanvas; Rect: TRect; Index: Integer); |
|
- | 259 | property Cells[Col, Row: Cardinal]: TBitmap read GetCell; |
|
- | 260 | property GraphicCell[Index: Integer]: TBitmap read GetGraphicCell; |
|
- | 261 | property IsEmpty: Boolean read GetIsEmpty; |
|
- | 262 | property Count: Integer read GetCount; |
|
- | 263 | published |
|
- | 264 | property Cols: TCellRange read FCols write FCols default 1; |
|
- | 265 | property Height: Integer read GetHeight write SetHeight stored False; |
|
- | 266 | property Masked: Boolean read FMasked write FMasked default True; |
|
- | 267 | property Rows: TCellRange read FRows write FRows default 1; |
|
- | 268 | property Picture: TPicture read FPicture write SetPicture; |
|
- | 269 | property MaskColor: TColor read FMaskColor write SetMaskColor stored IsMaskStored; |
|
- | 270 | property Width: Integer read GetWidth write SetWidth stored False; |
|
- | 271 | property OnChange: TNotifyEvent read FOnChange write FOnChange; |
|
- | 272 | end; |
|
- | 273 | ||
173 | function Max(Val1, Val2: Integer): Integer; |
274 | function Max(Val1, Val2: Integer): Integer; {$IFDEF VER9UP}inline;{$ENDIF} |
174 | function Min(Val1, Val2: Integer): Integer; |
275 | function Min(Val1, Val2: Integer): Integer; {$IFDEF VER9UP}inline;{$ENDIF} |
175 | 276 | ||
176 | function Cos256(i: Integer): Double; |
277 | function Cos256(i: Integer): Double; |
177 | function Sin256(i: Integer): Double; |
278 | function Sin256(i: Integer): Double; |
178 | 279 | ||
179 | function PointInRect(const Point: TPoint; const Rect: TRect): Boolean; |
280 | function PointInRect(const Point: TPoint; const Rect: TRect): Boolean; {$IFDEF VER9UP}inline;{$ENDIF} |
180 | function RectInRect(const Rect1, Rect2: TRect): Boolean; |
281 | function RectInRect(const Rect1, Rect2: TRect): Boolean; {$IFDEF VER9UP}inline;{$ENDIF} |
181 | function OverlapRect(const Rect1, Rect2: TRect): Boolean; |
282 | function OverlapRect(const Rect1, Rect2: TRect): Boolean; {$IFDEF VER9UP}inline;{$ENDIF} |
- | 283 | ||
- | 284 | function WideRect(ALeft, ATop, AWidth, AHeight: Integer): TRect; {$IFDEF VER9UP}inline;{$ENDIF} |
|
- | 285 | ||
- | 286 | { Transformations routines} |
|
- | 287 | ||
- | 288 | const |
|
- | 289 | L_Curve = 0;//The left curve |
|
- | 290 | R_Curve = 1;//The right curve |
|
- | 291 | ||
- | 292 | C_Add = 0;//Increase (BTC) |
|
- | 293 | C_Dec = 1;//Decrease (ETC) |
|
- | 294 | ||
- | 295 | Type |
|
- | 296 | TDblPoint = packed record |
|
- | 297 | X, Y: Double; |
|
- | 298 | end; |
|
- | 299 | TSngPoint = packed record //SinglePoint |
|
- | 300 | X, Y: Single; |
|
- | 301 | end; |
|
- | 302 | ||
- | 303 | ||
- | 304 | //Transformation matrix |
|
- | 305 | T2DRowCol = Array[1..3] of Array[1..3] of Double; |
|
- | 306 | T2DVector = Array[1..3] of Double; |
|
- | 307 | //Distance between 2 points |
|
- | 308 | function Get2PointRange(a,b: TDblPoint):Double; |
|
- | 309 | //From vector angular calculation |
|
- | 310 | function Get256(dX,dY: Double):Double; |
|
- | 311 | //The angular calculation of the A from B |
|
- | 312 | function GetARadFromB(A,B: TDblPoint):Double; |
|
- | 313 | ||
- | 314 | //It calculates the TDblPoint |
|
- | 315 | function DblPoint(a,b:Double):TDblPoint; |
|
- | 316 | //It converts the TDboPoint to the TPoint |
|
- | 317 | function TruncDblPoint(DblPos: TDblPoint): TPoint; |
|
- | 318 | ||
- | 319 | function GetPointFromRangeAndAngle(SP: TDblPoint; Range,Angle: Double): TDblPoint; |
|
- | 320 | ||
- | 321 | function Ini2DRowCol: T2DRowCol; |
|
- | 322 | function Trans2DRowCol(x,y:double):T2DRowCol; |
|
- | 323 | function Scale2DRowCol(x,y:double):T2DRowCol; |
|
- | 324 | function Rotate2DRowCol(Theta:double):T2DRowCol; |
|
- | 325 | function RotateIntoX2DRowCol(x,y: double):T2DRowCol; |
|
- | 326 | function Multiply2DRowCol(A,B:T2DRowCol):T2DRowCol; |
|
- | 327 | function ScaleAt2DRowCol(x,y,Sx,Sy:double):T2DRowCol; |
|
- | 328 | function ReflectAcross2DRowCol(x,y,dx,dy:Double): T2DRowCol; |
|
- | 329 | function Apply2DVector(V:T2DVector; M:T2DRowCol): T2DVector; |
|
- | 330 | function RotateAround2DRowCol(x,y,Theta:Double): T2DRowCol; |
|
- | 331 | ||
- | 332 | //Collision decision |
|
- | 333 | function PointInCircle(PPos,CPos: TPoint; R: integer): Boolean; |
|
- | 334 | function CircleInCircle(C1Pos,C2Pos: TPoint; R1,R2:Integer): Boolean; |
|
- | 335 | function SegmentInCircle(SPos,EPos,CPos: TPoint; R: Integer): Boolean; |
|
- | 336 | ||
- | 337 | //If A is closer than B from starting point S, the True is returned. |
|
- | 338 | function CheckNearAThanB(S,A,B: TDblPoint): Boolean; |
|
- | 339 | ||
- | 340 | //The Angle of 256 period is returned |
|
- | 341 | function Angle256(Angle: Single): Single; |
|
- | 342 | ||
- | 343 | { Support functions } |
|
182 | 344 | ||
183 | function WideRect(ALeft, ATop, AWidth, AHeight: Integer): TRect; |
- | |
184 | procedure ReleaseCom(out Com); |
345 | procedure ReleaseCom(out Com); |
185 | function DXLoadLibrary(const FileName, FuncName: string): TFarProc; |
346 | function DXLoadLibrary(const FileName, FuncName: string): TFarProc; |
186 | 347 | ||
- | 348 | { Simple helper } |
|
- | 349 | ||
- | 350 | procedure Log(const Co: string; const FName: string{$IFDEF VER4UP} = 'c:\logerr.txt'{$ENDIF}); |
|
- | 351 | ||
187 | implementation |
352 | implementation |
188 | 353 | ||
189 | uses DXConsts; |
354 | uses DXConsts; |
190 | 355 | ||
191 | function Max(Val1, Val2: Integer): Integer; |
356 | function Max(Val1, Val2: Integer): Integer; |
Line 688... | Line 853... | ||
688 | Item := Item.FRight; |
853 | Item := Item.FRight; |
689 | end; |
854 | end; |
690 | Result := -1; |
855 | Result := -1; |
691 | end; |
856 | end; |
692 | 857 | ||
- | 858 | { TDXPictureClip } |
|
- | 859 | ||
- | 860 | constructor TDXPictureClip.Create(AOwner: TComponent); |
|
- | 861 | begin |
|
- | 862 | inherited Create(AOwner); |
|
- | 863 | FPicture := TPicture.Create; |
|
- | 864 | FPicture.OnChange := PictureChanged; |
|
- | 865 | FBitmap := TBitmap.Create; |
|
- | 866 | FRows := 1; |
|
- | 867 | FCols := 1; |
|
- | 868 | FMaskColor := GetDefaultMaskColor; |
|
- | 869 | FMasked := True; |
|
- | 870 | end; |
|
- | 871 | ||
- | 872 | destructor TDXPictureClip.Destroy; |
|
- | 873 | begin |
|
- | 874 | FOnChange := nil; |
|
- | 875 | FPicture.OnChange := nil; |
|
- | 876 | FBitmap.Free; |
|
- | 877 | FPicture.Free; |
|
- | 878 | inherited Destroy; |
|
- | 879 | end; |
|
- | 880 | ||
- | 881 | procedure TDXPictureClip.Assign(Source: TPersistent); |
|
- | 882 | begin |
|
- | 883 | if Source is TDXPictureClip then begin |
|
- | 884 | with TDXPictureClip(Source) do begin |
|
- | 885 | Self.FRows := Rows; |
|
- | 886 | Self.FCols := Cols; |
|
- | 887 | Self.FMasked := Masked; |
|
- | 888 | Self.FMaskColor := MaskColor; |
|
- | 889 | Self.FPicture.Assign(FPicture); |
|
- | 890 | end; |
|
- | 891 | end |
|
- | 892 | else if (Source is TPicture) or (Source is TGraphic) then |
|
- | 893 | FPicture.Assign(Source) |
|
- | 894 | else inherited Assign(Source); |
|
- | 895 | end; |
|
- | 896 | ||
- | 897 | type |
|
- | 898 | THack = class(TImageList); |
|
- | 899 | ||
- | 900 | procedure TDXPictureClip.AssignTo(Dest: TPersistent); |
|
- | 901 | var |
|
- | 902 | I: Integer; |
|
- | 903 | SaveChange: TNotifyEvent; |
|
- | 904 | begin |
|
- | 905 | if (Dest is TPicture) then Dest.Assign(FPicture) |
|
- | 906 | else if (Dest is TImageList) and not IsEmpty then begin |
|
- | 907 | with TImageList(Dest) do begin |
|
- | 908 | SaveChange := OnChange; |
|
- | 909 | try |
|
- | 910 | OnChange := nil; |
|
- | 911 | Clear; |
|
- | 912 | Width := Self.Width; |
|
- | 913 | Height := Self.Height; |
|
- | 914 | for I := 0 to Self.Count - 1 do begin |
|
- | 915 | if Self.Masked and (MaskColor <> clNone) then |
|
- | 916 | TImageList(Dest).AddMasked(GraphicCell[I], MaskColor) |
|
- | 917 | else TImageList(Dest).Add(GraphicCell[I], nil); |
|
- | 918 | end; |
|
- | 919 | Masked := Self.Masked; |
|
- | 920 | finally |
|
- | 921 | OnChange := SaveChange; |
|
- | 922 | end; |
|
- | 923 | THack(Dest).Change; |
|
- | 924 | end; |
|
- | 925 | end |
|
- | 926 | else inherited AssignTo(Dest); |
|
- | 927 | end; |
|
- | 928 | ||
- | 929 | procedure TDXPictureClip.Changed; |
|
- | 930 | begin |
|
- | 931 | if Assigned(FOnChange) then FOnChange(Self); |
|
- | 932 | end; |
|
- | 933 | ||
- | 934 | function TDXPictureClip.GetIsEmpty: Boolean; |
|
- | 935 | begin |
|
- | 936 | Result := not Assigned(Picture) or Picture.Graphic.Empty; |
|
- | 937 | end; |
|
- | 938 | ||
- | 939 | function TDXPictureClip.GetCount: Integer; |
|
- | 940 | begin |
|
- | 941 | if IsEmpty then Result := 0 |
|
- | 942 | else Result := Cols * Rows; |
|
- | 943 | end; |
|
- | 944 | const |
|
- | 945 | { TBitmap.GetTransparentColor from GRAPHICS.PAS uses this value } |
|
- | 946 | PaletteMask = $02000000; |
|
- | 947 | ||
- | 948 | procedure TDXPictureClip.Draw(Canvas: TCanvas; X, Y, Index: Integer); |
|
- | 949 | ||
- | 950 | function PaletteColor(Color: TColor): Longint; |
|
- | 951 | begin |
|
- | 952 | Result := ColorToRGB(Color) or PaletteMask; |
|
- | 953 | end; |
|
- | 954 | procedure StretchBltTransparent(DstDC: HDC; DstX, DstY, DstW, DstH: Integer; |
|
- | 955 | SrcDC: HDC; SrcX, SrcY, SrcW, SrcH: Integer; Palette: HPalette; |
|
- | 956 | TransparentColor: TColorRef); |
|
- | 957 | var |
|
- | 958 | Color: TColorRef; |
|
- | 959 | bmAndBack, bmAndObject, bmAndMem, bmSave: HBitmap; |
|
- | 960 | bmBackOld, bmObjectOld, bmMemOld, bmSaveOld: HBitmap; |
|
- | 961 | MemDC, BackDC, ObjectDC, SaveDC: HDC; |
|
- | 962 | palDst, palMem, palSave, palObj: HPalette; |
|
- | 963 | begin |
|
- | 964 | { Create some DCs to hold temporary data } |
|
- | 965 | BackDC := CreateCompatibleDC(DstDC); |
|
- | 966 | ObjectDC := CreateCompatibleDC(DstDC); |
|
- | 967 | MemDC := CreateCompatibleDC(DstDC); |
|
- | 968 | SaveDC := CreateCompatibleDC(DstDC); |
|
- | 969 | { Create a bitmap for each DC } |
|
- | 970 | bmAndObject := CreateBitmap(SrcW, SrcH, 1, 1, nil); |
|
- | 971 | bmAndBack := CreateBitmap(SrcW, SrcH, 1, 1, nil); |
|
- | 972 | bmAndMem := CreateCompatibleBitmap(DstDC, DstW, DstH); |
|
- | 973 | bmSave := CreateCompatibleBitmap(DstDC, SrcW, SrcH); |
|
- | 974 | { Each DC must select a bitmap object to store pixel data } |
|
- | 975 | bmBackOld := SelectObject(BackDC, bmAndBack); |
|
- | 976 | bmObjectOld := SelectObject(ObjectDC, bmAndObject); |
|
- | 977 | bmMemOld := SelectObject(MemDC, bmAndMem); |
|
- | 978 | bmSaveOld := SelectObject(SaveDC, bmSave); |
|
- | 979 | { Select palette } |
|
- | 980 | palDst := 0; palMem := 0; palSave := 0; palObj := 0; |
|
- | 981 | if Palette <> 0 then begin |
|
- | 982 | palDst := SelectPalette(DstDC, Palette, True); |
|
- | 983 | RealizePalette(DstDC); |
|
- | 984 | palSave := SelectPalette(SaveDC, Palette, False); |
|
- | 985 | RealizePalette(SaveDC); |
|
- | 986 | palObj := SelectPalette(ObjectDC, Palette, False); |
|
- | 987 | RealizePalette(ObjectDC); |
|
- | 988 | palMem := SelectPalette(MemDC, Palette, True); |
|
- | 989 | RealizePalette(MemDC); |
|
- | 990 | end; |
|
- | 991 | { Set proper mapping mode } |
|
- | 992 | SetMapMode(SrcDC, GetMapMode(DstDC)); |
|
- | 993 | SetMapMode(SaveDC, GetMapMode(DstDC)); |
|
- | 994 | { Save the bitmap sent here } |
|
- | 995 | BitBlt(SaveDC, 0, 0, SrcW, SrcH, SrcDC, SrcX, SrcY, SRCCOPY); |
|
- | 996 | { Set the background color of the source DC to the color, } |
|
- | 997 | { contained in the parts of the bitmap that should be transparent } |
|
- | 998 | Color := SetBkColor(SaveDC, PaletteColor(TransparentColor)); |
|
- | 999 | { Create the object mask for the bitmap by performing a BitBlt() } |
|
- | 1000 | { from the source bitmap to a monochrome bitmap } |
|
- | 1001 | BitBlt(ObjectDC, 0, 0, SrcW, SrcH, SaveDC, 0, 0, SRCCOPY); |
|
- | 1002 | { Set the background color of the source DC back to the original } |
|
- | 1003 | SetBkColor(SaveDC, Color); |
|
- | 1004 | { Create the inverse of the object mask } |
|
- | 1005 | BitBlt(BackDC, 0, 0, SrcW, SrcH, ObjectDC, 0, 0, NOTSRCCOPY); |
|
- | 1006 | { Copy the background of the main DC to the destination } |
|
- | 1007 | BitBlt(MemDC, 0, 0, DstW, DstH, DstDC, DstX, DstY, SRCCOPY); |
|
- | 1008 | { Mask out the places where the bitmap will be placed } |
|
- | 1009 | StretchBlt(MemDC, 0, 0, DstW, DstH, ObjectDC, 0, 0, SrcW, SrcH, SRCAND); |
|
- | 1010 | { Mask out the transparent colored pixels on the bitmap } |
|
- | 1011 | BitBlt(SaveDC, 0, 0, SrcW, SrcH, BackDC, 0, 0, SRCAND); |
|
- | 1012 | { XOR the bitmap with the background on the destination DC } |
|
- | 1013 | StretchBlt(MemDC, 0, 0, DstW, DstH, SaveDC, 0, 0, SrcW, SrcH, SRCPAINT); |
|
- | 1014 | { Copy the destination to the screen } |
|
- | 1015 | BitBlt(DstDC, DstX, DstY, DstW, DstH, MemDC, 0, 0, |
|
- | 1016 | SRCCOPY); |
|
- | 1017 | { Restore palette } |
|
- | 1018 | if Palette <> 0 then begin |
|
- | 1019 | SelectPalette(MemDC, palMem, False); |
|
- | 1020 | SelectPalette(ObjectDC, palObj, False); |
|
- | 1021 | SelectPalette(SaveDC, palSave, False); |
|
- | 1022 | SelectPalette(DstDC, palDst, True); |
|
- | 1023 | end; |
|
- | 1024 | { Delete the memory bitmaps } |
|
- | 1025 | DeleteObject(SelectObject(BackDC, bmBackOld)); |
|
- | 1026 | DeleteObject(SelectObject(ObjectDC, bmObjectOld)); |
|
- | 1027 | DeleteObject(SelectObject(MemDC, bmMemOld)); |
|
- | 1028 | DeleteObject(SelectObject(SaveDC, bmSaveOld)); |
|
- | 1029 | { Delete the memory DCs } |
|
- | 1030 | DeleteDC(MemDC); |
|
- | 1031 | DeleteDC(BackDC); |
|
- | 1032 | DeleteDC(ObjectDC); |
|
- | 1033 | DeleteDC(SaveDC); |
|
- | 1034 | end; |
|
- | 1035 | procedure StretchBitmapTransparent(Dest: TCanvas; Bitmap: TBitmap; |
|
- | 1036 | TransparentColor: TColor; DstX, DstY, DstW, DstH, SrcX, SrcY, |
|
- | 1037 | SrcW, SrcH: Integer); |
|
- | 1038 | var |
|
- | 1039 | CanvasChanging: TNotifyEvent; |
|
- | 1040 | begin |
|
- | 1041 | if DstW <= 0 then DstW := Bitmap.Width; |
|
- | 1042 | if DstH <= 0 then DstH := Bitmap.Height; |
|
- | 1043 | if (SrcW <= 0) or (SrcH <= 0) then begin |
|
- | 1044 | SrcX := 0; SrcY := 0; |
|
- | 1045 | SrcW := Bitmap.Width; |
|
- | 1046 | SrcH := Bitmap.Height; |
|
- | 1047 | end; |
|
- | 1048 | if not Bitmap.Monochrome then |
|
- | 1049 | SetStretchBltMode(Dest.Handle, STRETCH_DELETESCANS); |
|
- | 1050 | CanvasChanging := Bitmap.Canvas.OnChanging; |
|
- | 1051 | Bitmap.Canvas.Lock; |
|
- | 1052 | try |
|
- | 1053 | Bitmap.Canvas.OnChanging := nil; |
|
- | 1054 | if TransparentColor = clNone then begin |
|
- | 1055 | StretchBlt(Dest.Handle, DstX, DstY, DstW, DstH, Bitmap.Canvas.Handle, |
|
- | 1056 | SrcX, SrcY, SrcW, SrcH, Dest.CopyMode); |
|
- | 1057 | end |
|
- | 1058 | else begin |
|
- | 1059 | if TransparentColor = clDefault then |
|
- | 1060 | TransparentColor := Bitmap.Canvas.Pixels[0, Bitmap.Height - 1]; |
|
- | 1061 | if Bitmap.Monochrome then TransparentColor := clWhite |
|
- | 1062 | else TransparentColor := ColorToRGB(TransparentColor); |
|
- | 1063 | StretchBltTransparent(Dest.Handle, DstX, DstY, DstW, DstH, |
|
- | 1064 | Bitmap.Canvas.Handle, SrcX, SrcY, SrcW, SrcH, Bitmap.Palette, |
|
- | 1065 | TransparentColor); |
|
- | 1066 | end; |
|
- | 1067 | finally |
|
- | 1068 | Bitmap.Canvas.OnChanging := CanvasChanging; |
|
- | 1069 | Bitmap.Canvas.Unlock; |
|
- | 1070 | end; |
|
- | 1071 | end; |
|
- | 1072 | procedure DrawBitmapTransparent(Dest: TCanvas; DstX, DstY: Integer; |
|
- | 1073 | Bitmap: TBitmap; TransparentColor: TColor); |
|
- | 1074 | begin |
|
- | 1075 | StretchBitmapTransparent(Dest, Bitmap, TransparentColor, DstX, DstY, |
|
- | 1076 | Bitmap.Width, Bitmap.Height, 0, 0, Bitmap.Width, Bitmap.Height); |
|
- | 1077 | end; |
|
- | 1078 | var |
|
- | 1079 | Image: TGraphic; |
|
- | 1080 | begin |
|
- | 1081 | if Index < 0 then Image := Picture.Graphic |
|
- | 1082 | else Image := GraphicCell[Index]; |
|
- | 1083 | if (Image <> nil) and not Image.Empty then begin |
|
- | 1084 | if FMasked and (FMaskColor <> clNone) and |
|
- | 1085 | (Picture.Graphic is TBitmap) then |
|
- | 1086 | DrawBitmapTransparent(Canvas, X, Y, TBitmap(Image), FMaskColor) |
|
- | 1087 | else Canvas.Draw(X, Y, Image); |
|
- | 1088 | end; |
|
- | 1089 | end; |
|
- | 1090 | ||
- | 1091 | procedure TDXPictureClip.DrawCenter(Canvas: TCanvas; Rect: TRect; Index: Integer); |
|
- | 1092 | var |
|
- | 1093 | X, Y: Integer; |
|
- | 1094 | begin |
|
- | 1095 | X := (Rect.Left + Rect.Right - Width) div 2; |
|
- | 1096 | Y := (Rect.Bottom + Rect.Top - Height) div 2; |
|
- | 1097 | Draw(Canvas, X, Y, Index); |
|
- | 1098 | end; |
|
- | 1099 | ||
- | 1100 | procedure TDXPictureClip.CheckIndex(Index: Integer); |
|
- | 1101 | begin |
|
- | 1102 | if (Index >= Cols * Rows) or (Index < 0) then |
|
- | 1103 | raise EListError.CreateFmt('%s (%d)', ['Load list error', Index]); |
|
- | 1104 | end; |
|
- | 1105 | ||
- | 1106 | function TDXPictureClip.GetIndex(Col, Row: Cardinal): Integer; |
|
- | 1107 | begin |
|
- | 1108 | Result := Col + (Row * Cols); |
|
- | 1109 | if (Result >= Cols * Rows) or IsEmpty then Result := -1; |
|
- | 1110 | end; |
|
- | 1111 | ||
- | 1112 | function TDXPictureClip.GetCell(Col, Row: Cardinal): TBitmap; |
|
- | 1113 | begin |
|
- | 1114 | Result := GetGraphicCell(GetIndex(Col, Row)); |
|
- | 1115 | end; |
|
- | 1116 | ||
- | 1117 | function TDXPictureClip.GetGraphicCell(Index: Integer): TBitmap; |
|
- | 1118 | procedure AssignBitmapCell(Source: TGraphic; Dest: TBitmap; Cols, Rows, |
|
- | 1119 | Index: Integer); |
|
- | 1120 | var |
|
- | 1121 | CellWidth, CellHeight: Integer; |
|
- | 1122 | begin |
|
- | 1123 | if (Source <> nil) and (Dest <> nil) then begin |
|
- | 1124 | if Cols <= 0 then Cols := 1; |
|
- | 1125 | if Rows <= 0 then Rows := 1; |
|
- | 1126 | if Index < 0 then Index := 0; |
|
- | 1127 | CellWidth := Source.Width div Cols; |
|
- | 1128 | CellHeight := Source.Height div Rows; |
|
- | 1129 | with Dest do begin |
|
- | 1130 | Width := CellWidth; Height := CellHeight; |
|
- | 1131 | end; |
|
- | 1132 | if Source is TBitmap then begin |
|
- | 1133 | Dest.Canvas.CopyRect(Bounds(0, 0, CellWidth, CellHeight), |
|
- | 1134 | TBitmap(Source).Canvas, Bounds((Index mod Cols) * CellWidth, |
|
- | 1135 | (Index div Cols) * CellHeight, CellWidth, CellHeight)); |
|
- | 1136 | Dest.TransparentColor := TBitmap(Source).TransparentColor; |
|
- | 1137 | end |
|
- | 1138 | else begin |
|
- | 1139 | Dest.Canvas.Brush.Color := clSilver; |
|
- | 1140 | Dest.Canvas.FillRect(Bounds(0, 0, CellWidth, CellHeight)); |
|
- | 1141 | Dest.Canvas.Draw(-(Index mod Cols) * CellWidth, |
|
- | 1142 | -(Index div Cols) * CellHeight, Source); |
|
- | 1143 | end; |
|
- | 1144 | Dest.Transparent := Source.Transparent; |
|
- | 1145 | end; |
|
- | 1146 | end; |
|
- | 1147 | begin |
|
- | 1148 | CheckIndex(Index); |
|
- | 1149 | AssignBitmapCell(Picture.Graphic, FBitmap, Cols, Rows, Index); |
|
- | 1150 | if Picture.Graphic is TBitmap then |
|
- | 1151 | if FBitmap.PixelFormat <> pfDevice then |
|
- | 1152 | FBitmap.PixelFormat := TBitmap(Picture.Graphic).PixelFormat; |
|
- | 1153 | FBitmap.TransparentColor := FMaskColor or PaletteMask; |
|
- | 1154 | FBitmap.Transparent := (FMaskColor <> clNone) and Masked; |
|
- | 1155 | Result := FBitmap; |
|
- | 1156 | end; |
|
- | 1157 | ||
- | 1158 | function TDXPictureClip.GetDefaultMaskColor: TColor; |
|
- | 1159 | begin |
|
- | 1160 | Result := clOlive; |
|
- | 1161 | if (Picture.Graphic <> nil) and (Picture.Graphic is TBitmap) then |
|
- | 1162 | Result := TBitmap(Picture.Graphic).TransparentColor and |
|
- | 1163 | not PaletteMask; |
|
- | 1164 | end; |
|
- | 1165 | ||
- | 1166 | function TDXPictureClip.GetHeight: Integer; |
|
- | 1167 | begin |
|
- | 1168 | Result := Picture.Height div FRows; |
|
- | 1169 | end; |
|
- | 1170 | ||
- | 1171 | function TDXPictureClip.GetWidth: Integer; |
|
- | 1172 | begin |
|
- | 1173 | Result := Picture.Width div FCols; |
|
- | 1174 | end; |
|
- | 1175 | ||
- | 1176 | function TDXPictureClip.IsMaskStored: Boolean; |
|
- | 1177 | begin |
|
- | 1178 | Result := MaskColor <> GetDefaultMaskColor; |
|
- | 1179 | end; |
|
- | 1180 | ||
- | 1181 | procedure TDXPictureClip.SetMaskColor(Value: TColor); |
|
- | 1182 | begin |
|
- | 1183 | if Value <> FMaskColor then begin |
|
- | 1184 | FMaskColor := Value; |
|
- | 1185 | Changed; |
|
- | 1186 | end; |
|
- | 1187 | end; |
|
- | 1188 | ||
- | 1189 | procedure TDXPictureClip.PictureChanged(Sender: TObject); |
|
- | 1190 | begin |
|
- | 1191 | FMaskColor := GetDefaultMaskColor; |
|
- | 1192 | if not (csReading in ComponentState) then Changed; |
|
- | 1193 | end; |
|
- | 1194 | ||
- | 1195 | procedure TDXPictureClip.SetHeight(Value: Integer); |
|
- | 1196 | begin |
|
- | 1197 | if (Value > 0) and (Picture.Height div Value > 0) then |
|
- | 1198 | Rows := Picture.Height div Value; |
|
- | 1199 | end; |
|
- | 1200 | ||
- | 1201 | procedure TDXPictureClip.SetWidth(Value: Integer); |
|
- | 1202 | begin |
|
- | 1203 | if (Value > 0) and (Picture.Width div Value > 0) then |
|
- | 1204 | Cols := Picture.Width div Value; |
|
- | 1205 | end; |
|
- | 1206 | ||
- | 1207 | procedure TDXPictureClip.SetPicture(Value: TPicture); |
|
- | 1208 | begin |
|
- | 1209 | FPicture.Assign(Value); |
|
- | 1210 | end; |
|
- | 1211 | ||
- | 1212 | { Transformations routines } |
|
- | 1213 | { Authorisation: Mr. Takanori Kawasaki} |
|
- | 1214 | ||
- | 1215 | //Distance between 2 points is calculated |
|
- | 1216 | function Get2PointRange(a,b: TDblPoint):Double; |
|
- | 1217 | var |
|
- | 1218 | x,y: Double; |
|
- | 1219 | begin |
|
- | 1220 | x := a.X - b.X; |
|
- | 1221 | y := a.Y - b.Y; |
|
- | 1222 | Result := Sqrt(x*x+y*y); |
|
- | 1223 | end; |
|
- | 1224 | ||
- | 1225 | //Direction angle in the coordinate A which was seen from coordinate B is calculated |
|
- | 1226 | function GetARadFromB(A,B: TDblPoint):Double; |
|
- | 1227 | var |
|
- | 1228 | dX,dY: Double; |
|
- | 1229 | begin |
|
- | 1230 | dX := A.X - B.X; |
|
- | 1231 | dY := A.Y - B.Y; |
|
- | 1232 | Result := Get256(dX,dY); |
|
- | 1233 | end; |
|
- | 1234 | ||
- | 1235 | //Direction angle is returned with 0 - 255. |
|
- | 1236 | function Get256(dX,dY:Double):Double; |
|
- | 1237 | begin |
|
- | 1238 | Result := 0; |
|
- | 1239 | if dX > 0 then |
|
- | 1240 | begin//0-63 |
|
- | 1241 | if dY > 0 then Result := ArcTan(dY / dX) // 0 < Res < 90 |
|
- | 1242 | else//0 |
|
- | 1243 | if dY = 0 then Result := 0 // 0 |
|
- | 1244 | else//192-255 |
|
- | 1245 | if dY < 0 then Result := 2*Pi + ArcTan(dY / dX) // 270 < Res < 360 |
|
- | 1246 | end else |
|
- | 1247 | if dX = 0 then |
|
- | 1248 | begin//64 |
|
- | 1249 | if dY > 0 then Result := 1 / 2 * Pi // 90 |
|
- | 1250 | else//0 |
|
- | 1251 | if dY = 0 then Result := 0 // 0 |
|
- | 1252 | else//192 |
|
- | 1253 | if dY < 0 then Result := 3 / 2 * Pi // 270 |
|
- | 1254 | end else |
|
- | 1255 | if dX < 0 then |
|
- | 1256 | begin//64-127 |
|
- | 1257 | if dY > 0 then Result := Pi + ArcTan(dY / dX) // 90 < Res < 180 |
|
- | 1258 | else//128 |
|
- | 1259 | if dY = 0 then Result := Pi // 180 |
|
- | 1260 | else//128-191 |
|
- | 1261 | if dY < 0 then Result := Pi + ArcTan(dY / dX) // 180 < Res < 270 |
|
- | 1262 | end; |
|
- | 1263 | Result := 256 * Result / (2*Pi); |
|
- | 1264 | end; |
|
- | 1265 | ||
- | 1266 | //From the coordinate SP the Range it calculates the point which leaves with the angular Angle |
|
- | 1267 | function GetPointFromRangeAndAngle(SP: TDblPoint; Range,Angle: Double): TDblPoint; |
|
- | 1268 | begin |
|
- | 1269 | Result.X := SP.X + Range * Cos(Angle); |
|
- | 1270 | Result.Y := SP.Y + Range * Sin(Angle); |
|
- | 1271 | end; |
|
- | 1272 | ||
- | 1273 | //* As for coordinate transformation coordinate for mathematics is used |
|
- | 1274 | //Identity matrix for the 2d is returned. |
|
- | 1275 | function Ini2DRowCol: T2DRowCol; |
|
- | 1276 | var |
|
- | 1277 | i,ii:integer; |
|
- | 1278 | begin |
|
- | 1279 | for i := 1 to 3 do |
|
- | 1280 | for ii := 1 to 3 do |
|
- | 1281 | if i = ii then Result[i,ii] := 1 else Result[i,ii] := 0; |
|
- | 1282 | end; |
|
- | 1283 | ||
- | 1284 | //Transformation matrix of the portable quantity |
|
- | 1285 | //where the one for 2d is appointed is returned. |
|
- | 1286 | function Trans2DRowCol(x,y:double):T2DRowCol; |
|
- | 1287 | begin |
|
- | 1288 | Result := Ini2DRowCol; |
|
- | 1289 | Result[3,1] := x; |
|
- | 1290 | Result[3,2] := y; |
|
- | 1291 | end; |
|
- | 1292 | ||
- | 1293 | //Conversion coordinate of the expansion and contraction |
|
- | 1294 | //quantity where the one for 2d is appointed is returned. |
|
- | 1295 | function Scale2DRowCol(x,y:double):T2DRowCol; |
|
- | 1296 | begin |
|
- | 1297 | Result := Ini2DRowCol; |
|
- | 1298 | Result[1,1] := x; |
|
- | 1299 | Result[2,2] := y; |
|
- | 1300 | end; |
|
- | 1301 | ||
- | 1302 | //Coordinate transformation of the rotary quantity |
|
- | 1303 | //where the one for 2d is appointed is returned. |
|
- | 1304 | function Rotate2DRowCol(Theta:double):T2DRowCol; |
|
- | 1305 | begin |
|
- | 1306 | Result := Ini2DRowCol; |
|
- | 1307 | Result[1,1] := Cos256(Trunc(Theta)); |
|
- | 1308 | Result[1,2] := Sin256(Trunc(Theta)); |
|
- | 1309 | Result[2,1] := -1 * Result[1,2]; |
|
- | 1310 | Result[2,2] := Result[1,1]; |
|
- | 1311 | end; |
|
- | 1312 | ||
- | 1313 | //You apply two conversion coordinates and adjust. |
|
- | 1314 | function Multiply2DRowCol(A,B:T2DRowCol):T2DRowCol; |
|
- | 1315 | begin |
|
- | 1316 | Result[1,1] := A[1,1] * B[1,1] + A[1,2] * B[2,1]; |
|
- | 1317 | Result[1,2] := A[1,1] * B[1,2] + A[1,2] * B[2,2]; |
|
- | 1318 | Result[1,3] := 0; |
|
- | 1319 | Result[2,1] := A[2,1] * B[1,1] + A[2,2] * B[2,1]; |
|
- | 1320 | Result[2,2] := A[2,1] * B[1,2] + A[2,2] * B[2,2]; |
|
- | 1321 | Result[2,3] := 0; |
|
- | 1322 | Result[3,1] := A[3,1] * B[1,1] + A[3,2] * B[2,1] + B[3,1]; |
|
- | 1323 | Result[3,2] := A[3,1] * B[1,2] + A[3,2] * B[2,2] + B[3,2]; |
|
- | 1324 | Result[3,3] := 1; |
|
- | 1325 | end; |
|
- | 1326 | ||
- | 1327 | //Until coordinate (the X and the Y) comes on the X axis, |
|
- | 1328 | //the conversion coordinate which turns the position |
|
- | 1329 | //of the point is returned. |
|
- | 1330 | function RotateIntoX2DRowCol(x,y: double):T2DRowCol; |
|
- | 1331 | var |
|
- | 1332 | d: double; |
|
- | 1333 | begin |
|
- | 1334 | Result := Ini2DRowCol; |
|
- | 1335 | d := sqrt(x*x+y*y); |
|
- | 1336 | Result[1,1] := x / d; |
|
- | 1337 | Result[1,2] := y / d; |
|
- | 1338 | Result[2,1] := -1 * Result[1,2]; |
|
- | 1339 | Result[2,2] := Result[1,1]; |
|
- | 1340 | end; |
|
- | 1341 | ||
- | 1342 | //Coordinate (the X and the Y) as a center, the conversion |
|
- | 1343 | //coordinate which does the scaling of the magnification ratio |
|
- | 1344 | //which is appointed with the Sx and the Sy is returned. |
|
- | 1345 | function ScaleAt2DRowCol(x,y,Sx,Sy:double):T2DRowCol; |
|
- | 1346 | var |
|
- | 1347 | T,S,TInv,M:T2DRowCol; |
|
- | 1348 | begin |
|
- | 1349 | T := Trans2DRowCol(-x,-y); |
|
- | 1350 | TInv := Trans2DRowCol(x,y); |
|
- | 1351 | S := Scale2DRowCol(Sx,Sy); |
|
- | 1352 | M := Multiply2DRowCol(T,S); |
|
- | 1353 | Result := Multiply2DRowCol(M,T); |
|
- | 1354 | end; |
|
- | 1355 | ||
- | 1356 | //Coordinate (the X and the Y) it passes, comes hard and |
|
- | 1357 | //(DX and the dy) with the direction which is shown it |
|
- | 1358 | //returns the transformation matrix which does the reflected |
|
- | 1359 | //image conversion which centers the line which faces. |
|
- | 1360 | function ReflectAcross2DRowCol(x,y,dx,dy:Double): T2DRowCol; |
|
- | 1361 | var |
|
- | 1362 | T,R,S,RInv,TInv,M1,M2,M3: T2DRowCol; |
|
- | 1363 | begin |
|
- | 1364 | T := Trans2DRowCol(-x,-y); |
|
- | 1365 | TInv := Trans2DRowCol(x,y); |
|
- | 1366 | R := RotateIntoX2DRowCol(dx,dy); |
|
- | 1367 | RInv := RotateIntoX2DRowCol(dx,-dy); |
|
- | 1368 | S := Scale2DRowCol(1,-1); |
|
- | 1369 | M1 := Multiply2DRowCol(T,R); |
|
- | 1370 | M2 := Multiply2DRowCol(S,RInv); |
|
- | 1371 | M3 := Multiply2DRowCol(M1,M2); |
|
- | 1372 | Result := Multiply2DRowCol(M3,TInv); |
|
- | 1373 | end; |
|
- | 1374 | ||
- | 1375 | //Coordinate focusing on (the X and the Y) the transformation |
|
- | 1376 | //matrix which turns the position of the point with angle Theta is returned. |
|
- | 1377 | function RotateAround2DRowCol(x,y,Theta:Double): T2DRowCol; |
|
- | 1378 | var |
|
- | 1379 | T,R,TInv,M: T2DRowCol; |
|
- | 1380 | begin |
|
- | 1381 | T := Trans2DRowCol(-x,-y); |
|
- | 1382 | TInv := Trans2DRowCol(x,y); |
|
- | 1383 | R := Rotate2DRowCol(Theta); |
|
- | 1384 | M := Multiply2DRowCol(T,R); |
|
- | 1385 | Result := Multiply2DRowCol(M,TInv); |
|
- | 1386 | end; |
|
- | 1387 | ||
- | 1388 | //Transformation matrix is applied to the point. |
|
- | 1389 | function Apply2DVector(V:T2DVector; M:T2DRowCol): T2DVector; |
|
- | 1390 | begin |
|
- | 1391 | Result[1] := V[1] * M[1,1] + V[2] * M[2,1] + M[3,1]; |
|
- | 1392 | Result[2] := V[1] * M[1,2] + V[2] * M[2,2] + M[3,2]; |
|
- | 1393 | Result[3] := 1; |
|
- | 1394 | end; |
|
- | 1395 | ||
- | 1396 | //The TDblPoint is returned |
|
- | 1397 | function DblPoint(a,b:Double):TDblPoint; |
|
- | 1398 | begin |
|
- | 1399 | Result.X := a; |
|
- | 1400 | Result.Y := b; |
|
- | 1401 | end; |
|
- | 1402 | ||
- | 1403 | function TruncDblPoint(DblPos: TDblPoint): TPoint; |
|
- | 1404 | begin |
|
- | 1405 | Result.X := Trunc(DblPos.X); |
|
- | 1406 | Result.Y := Trunc(DblPos.Y); |
|
- | 1407 | end; |
|
- | 1408 | { |
|
- | 1409 | +-----------------------------------------------------------------------------+ |
|
- | 1410 | |Collision decision | |
|
- | 1411 | +-----------------------------------------------------------------------------+} |
|
- | 1412 | ||
- | 1413 | //Point and circle |
|
- | 1414 | function PointInCircle(PPos,CPos: TPoint; R: integer): Boolean; |
|
- | 1415 | begin |
|
- | 1416 | Result := (PPos.X - CPos.X)*(PPos.X - CPos.X)+(PPos.Y - CPos.Y)*(PPos.Y - CPos.Y)<= R*R; |
|
- | 1417 | end; |
|
- | 1418 | ||
- | 1419 | //Circle and circle |
|
- | 1420 | function CircleInCircle(C1Pos,C2Pos: TPoint; R1,R2:Integer): Boolean; |
|
- | 1421 | begin |
|
- | 1422 | Result := (C1Pos.X - C2Pos.X)*(C1Pos.X - C2Pos.X)+(C1Pos.Y - C2Pos.Y)*(C1Pos.Y - C2Pos.Y) <= (R1+R2)*(R1+R2); |
|
- | 1423 | end; |
|
- | 1424 | ||
- | 1425 | //Circle and line segment |
|
- | 1426 | function SegmentInCircle(SPos,EPos,CPos: TPoint; R: Integer): Boolean; |
|
- | 1427 | var |
|
- | 1428 | V,C: TPoint; |
|
- | 1429 | VC,VV,CC:integer; |
|
- | 1430 | begin |
|
- | 1431 | Result := False; |
|
- | 1432 | V.X := EPos.X - SPos.X; V.Y := EPos.Y - SPos.Y; |
|
- | 1433 | C.X := CPos.X - SPos.X; C.Y := CPos.Y - SPos.Y; |
|
- | 1434 | VC := V.X * C.X + V.Y * C.Y; |
|
- | 1435 | if VC < 0 then |
|
- | 1436 | begin |
|
- | 1437 | Result := (C.X * C.X + C.Y * C.Y) <= R*R; |
|
- | 1438 | end |
|
- | 1439 | else |
|
- | 1440 | begin |
|
- | 1441 | VV := V.X * V.X + V.Y * V.Y; |
|
- | 1442 | if VC >= VV then |
|
- | 1443 | begin |
|
- | 1444 | Result := (EPos.X - CPos.X)*(EPos.X - CPos.X)+(EPos.Y - CPos.Y)*(EPos.Y - CPos.Y) <= R * R; |
|
- | 1445 | end |
|
- | 1446 | else |
|
- | 1447 | if VC < VV then |
|
- | 1448 | begin |
|
- | 1449 | CC := C.X * C.X + C.Y * C.Y; |
|
- | 1450 | Result := CC - (VC div VV)* VC <= R*R; |
|
- | 1451 | end; |
|
- | 1452 | end; |
|
- | 1453 | end; |
|
- | 1454 | ||
- | 1455 | //Angle recalc |
|
- | 1456 | function Angle256(Angle: Single): Single; |
|
- | 1457 | begin |
|
- | 1458 | Result := Angle; |
|
- | 1459 | While Result < 0 do Result := Result + 256; |
|
- | 1460 | While Result >= 256 do Result := Result -256; |
|
- | 1461 | end; |
|
- | 1462 | ||
- | 1463 | //If A is closer than B from starting point S, the True is returned. |
|
- | 1464 | function CheckNearAThanB(S,A,B: TDblPoint): Boolean; |
|
- | 1465 | begin |
|
- | 1466 | Result := (S.X-A.X)*(S.X-A.X)+(S.Y-A.Y)*(S.Y-A.Y) <= (S.X-B.X)*(S.X-B.X)+(S.Y-B.Y)*(S.Y-B.Y); |
|
- | 1467 | end; |
|
- | 1468 | ||
- | 1469 | function CircumCenter3Pt(const x1, y1, x2, y2, x3, y3: Single; out Px, Py: Single): Boolean; |
|
- | 1470 | var |
|
- | 1471 | A,B,C,D,E,F,G: Single; |
|
- | 1472 | begin |
|
- | 1473 | A := x2 - x1; |
|
- | 1474 | B := y2 - y1; |
|
- | 1475 | C := x3 - x1; |
|
- | 1476 | D := y3 - y1; |
|
- | 1477 | E := A * (x1 + x2) + B * (y1 + y2); |
|
- | 1478 | F := C * (x1 + x3) + D * (y1 + y3); |
|
- | 1479 | G := 2.0 * (A * (y3 - y2) - B * (x3 - x2)); |
|
- | 1480 | Result := G <> 0.0; |
|
- | 1481 | if Result then begin |
|
- | 1482 | Px := (D * E - B * F) / G; |
|
- | 1483 | Py := (A * F - C * E) / G; |
|
- | 1484 | end; |
|
- | 1485 | end; |
|
- | 1486 | ||
- | 1487 | function Distance(const x1, y1, x2, y2: Double): Double; |
|
- | 1488 | begin |
|
- | 1489 | Result := Sqrt(Sqr(y2 - y1) + Sqr(x2 - x1)); |
|
- | 1490 | end; |
|
- | 1491 | ||
- | 1492 | procedure InCenter(const x1, y1, x2, y2, x3, y3: Double; out Px, Py: Double); |
|
- | 1493 | var |
|
- | 1494 | Perim: Double; |
|
- | 1495 | Side12: Double; |
|
- | 1496 | Side23: Double; |
|
- | 1497 | Side31: Double; |
|
- | 1498 | begin |
|
- | 1499 | Side12 := Distance(x1, y1, x2, y2); |
|
- | 1500 | Side23 := Distance(x2, y2, x3, y3); |
|
- | 1501 | Side31 := Distance(x3, y3, x1, y1); |
|
- | 1502 | { Using Heron's S=UR } |
|
- | 1503 | Perim := 1.0 / (Side12 + Side23 + Side31); |
|
- | 1504 | Px := (Side23 * x1 + Side31 * x2 + Side12 * x3) * Perim; |
|
- | 1505 | Py := (Side23 * y1 + Side31 * y2 + Side12 * y3) * Perim; |
|
- | 1506 | end; |
|
- | 1507 | ||
- | 1508 | function PointInTriangle(const Px, Py, x1, y1, x2, y2, x3, y3: Double): Boolean; |
|
- | 1509 | function Orientation(const x1, y1, x2, y2, Px, Py: Double): Integer; |
|
- | 1510 | var |
|
- | 1511 | Orin: Double; |
|
- | 1512 | begin |
|
- | 1513 | (* Linear determinant of the 3 points *) |
|
- | 1514 | Orin := (x2 - x1) * (py - y1) - (px - x1) * (y2 - y1); |
|
- | 1515 | ||
- | 1516 | if Orin > 0.0 then |
|
- | 1517 | Result := +1 (* Orientaion is to the right-hand side *) |
|
- | 1518 | else if Orin < 0.0 then |
|
- | 1519 | Result := -1 (* Orientaion is to the left-hand side *) |
|
- | 1520 | else |
|
- | 1521 | Result := 0; (* Orientaion is neutral aka collinear *) |
|
- | 1522 | end; |
|
- | 1523 | var |
|
- | 1524 | Or1, Or2, Or3: Integer; |
|
- | 1525 | begin |
|
- | 1526 | Or1 := Orientation(x1, y1, x2, y2, Px, Py); |
|
- | 1527 | Or2 := Orientation(x2, y2, x3, y3, Px, Py); |
|
- | 1528 | Or3 := Orientation(x3, y3, x1, y1, Px, Py); |
|
- | 1529 | ||
- | 1530 | if (Or1 = Or2) and (Or2 = Or3) then |
|
- | 1531 | Result := True |
|
- | 1532 | else if Or1 = 0 then |
|
- | 1533 | Result := (Or2 = 0) or (Or3 = 0) |
|
- | 1534 | else if Or2 = 0 then |
|
- | 1535 | Result := (Or1 = 0) or (Or3 = 0) |
|
- | 1536 | else if Or3 = 0 then |
|
- | 1537 | Result := (Or2 = 0) or (Or1 = 0) |
|
- | 1538 | else |
|
- | 1539 | Result := False; |
|
- | 1540 | end; |
|
- | 1541 | ||
- | 1542 | procedure Log(const Co: string; const FName: string); |
|
- | 1543 | var F: Text; D: TDateTime; |
|
- | 1544 | Hour, Minute, Second, MSec: Word; |
|
- | 1545 | begin |
|
- | 1546 | AsSignFile(F, FName); |
|
- | 1547 | if FileExists(FName) then Append(F) |
|
- | 1548 | else ReWrite(F); |
|
- | 1549 | try |
|
- | 1550 | D := Now; |
|
- | 1551 | DecodeTime(D, Hour, Minute, Second, MSec); |
|
- | 1552 | WriteLn(F, DateToStr(D) + ' ' + IntToStr(Hour)+':'+IntToStr(Minute)+':'+IntToStr(Second)+ '.'+IntToStr(MSec) +' ' + Co); |
|
- | 1553 | finally |
|
- | 1554 | CloseFile(F); |
|
- | 1555 | end; |
|
- | 1556 | end; |
|
- | 1557 | ||
- | 1558 | {$IFDEF _DMO_} |
|
- | 1559 | ||
- | 1560 | { TDirectXDriverEx } |
|
- | 1561 | ||
- | 1562 | function TDirectXDriverEx.ConvertHMonitor(iMonitor: HMonitor): TMonitorInfo; |
|
- | 1563 | begin |
|
- | 1564 | ZeroMemory(@Result, sizeof(Result)); |
|
- | 1565 | Result.cbSize := SizeOf(Result); |
|
- | 1566 | MultiMon.GetMonitorInfo(iMonitor, @Result); |
|
- | 1567 | end; |
|
- | 1568 | ||
- | 1569 | function TDirectXDriverEx.GetFlags: DWORD; |
|
- | 1570 | begin |
|
- | 1571 | Result := ConvertHMonitor(FMonitor).dwFlags; |
|
- | 1572 | end; |
|
- | 1573 | ||
- | 1574 | function TDirectXDriverEx.GetMonitorInfo: TMonitorInfo; |
|
- | 1575 | begin |
|
- | 1576 | Result:= ConvertHMonitor(FMonitor); |
|
- | 1577 | end; |
|
- | 1578 | ||
- | 1579 | function TDirectXDriverEx.GetTempSpace: TRect; |
|
- | 1580 | begin |
|
- | 1581 | Result := ConvertHMonitor(FMonitor).rcWork |
|
- | 1582 | end; |
|
- | 1583 | ||
- | 1584 | function TDirectXDriverEx.GetWorkSpace: TRect; |
|
- | 1585 | begin |
|
- | 1586 | Result := ConvertHMonitor(FMonitor).rcMonitor |
|
- | 1587 | end; |
|
- | 1588 | ||
- | 1589 | procedure TDirectXDriverEx.SetGUID(Value: PGUID); |
|
- | 1590 | begin |
|
- | 1591 | if not IsBadHugeReadPtr(Value, SizeOf(TGUID)) then |
|
- | 1592 | begin |
|
- | 1593 | FGUID2 := Value^; |
|
- | 1594 | FGUID := @FGUID2; |
|
- | 1595 | end else |
|
- | 1596 | FGUID := Value; |
|
- | 1597 | end; |
|
- | 1598 | ||
- | 1599 | { TDirectXDriversEx } |
|
- | 1600 | ||
- | 1601 | constructor TDirectXDriversEx.Create; |
|
- | 1602 | begin |
|
- | 1603 | inherited Create(TDirectXDriverEx); |
|
- | 1604 | end; |
|
- | 1605 | ||
- | 1606 | function TDirectXDriversEx.GetDriver(Index: Integer): TDirectXDriverEx; |
|
- | 1607 | begin |
|
- | 1608 | Result := (inherited Items[Index]) as TDirectXDriverEx; |
|
- | 1609 | end; |
|
- | 1610 | ||
- | 1611 | {$ENDIF} |
|
- | 1612 | ||
693 | initialization |
1613 | initialization |
694 | InitCosinTable; |
1614 | InitCosinTable; |
695 | finalization |
1615 | finalization |
696 | FreeLibList; |
1616 | FreeLibList; |
697 | end. |
1617 | end. |