Luxophia

Форк
0
/
LUX.Geometry.D2.pas 
825 строк · 18.7 Кб
1
unit LUX.Geometry.D2;
2

3
interface
4

5
uses
6
  System.SysUtils,
7
  System.Math,
8

9
  LUX,
10
  LUX.D1,
11
  LUX.D2,
12
  LUX.M2,
13
  LUX.Geometry;
14

15
type
16
  // Circles
17
  TSingleCircl2 = record
18
  private
19
  public
20
    Center: TSingle2D;
21
    Radiu2: Single;
22
    constructor Create(const P1_, P2_, P3_: TSingle2D); overload;
23
  end;
24

25
  TDoubleCircl2 = record
26
  private
27
  public
28
    Center: TDouble2D;
29
    Radiu2: Double;
30
    constructor Create(const P1_, P2_, P3_: TDouble2D); overload;
31
  end;
32

33
  TSingleCircle = record
34
  private
35
  public
36
    Center: TSingle2D;
37
    Radius: Single;
38
    constructor Create(const P1_, P2_, P3_: TSingle2D); overload;
39
    class operator Implicit(const Circl2_: TSingleCircl2): TSingleCircle;
40
    class operator Implicit(const Circle_: TSingleCircle): TSingleCircl2;
41
  end;
42

43
  TDoubleCircle = record
44
  private
45
  public
46
    Center: TDouble2D;
47
    Radius: Double;
48
    constructor Create(const P1_, P2_, P3_: TDouble2D); overload;
49
    class operator Implicit(const Circl2_: TDoubleCircl2): TDoubleCircle;
50
    class operator Implicit(const Circle_: TDoubleCircle): TDoubleCircl2;
51
  end;
52

53
  // Trials
54
  // P3              P* :Poin*
55
  // │\            E* :Edge*
56
  // │  \          N* :Enor*
57
  // │    \
58
  // E2─N2  E1
59
  // │    /  \
60
  // │  N1  N3  \
61
  // │      │    \
62
  // P1───E3───P2
63

64
  TSingleTria2D = record
65
  private
66
    function GetNorv: Single;
67
    function GetEdge1: TSingle2D;
68
    function GetEdge2: TSingle2D;
69
    function GetEdge3: TSingle2D;
70
    function GetEnor1: TSingle2D;
71
    function GetEnor2: TSingle2D;
72
    function GetEnor3: TSingle2D;
73
    function GetAABB: TSingleArea2D;
74
  public
75
    Poin1: TSingle2D;
76
    Poin2: TSingle2D;
77
    Poin3: TSingle2D;
78
    property Norv: Single read GetNorv;
79
    property Edge1: TSingle2D read GetEdge1;
80
    property Edge2: TSingle2D read GetEdge2;
81
    property Edge3: TSingle2D read GetEdge3;
82
    property Enor1: TSingle2D read GetEnor1;
83
    property Enor2: TSingle2D read GetEnor2;
84
    property Enor3: TSingle2D read GetEnor3;
85
    property AABB: TSingleArea2D read GetAABB;
86
    function ColliEdge(const Area_: TSingleArea2D): Boolean;
87
    function Collision(const Area_: TSingleArea2D): Boolean;
88
  end;
89

90
  // P3              P* :Poin*
91
  // │\            E* :Edge*
92
  // │  \          N* :Enor*
93
  // │    \
94
  // E2─N2  E1
95
  // │    /  \
96
  // │  N1  N3  \
97
  // │      │    \
98
  // P1───E3───P2
99

100
  TDoubleTria2D = record
101
  private
102
    function GetNorv: Double;
103
    function GetEdge1: TDouble2D;
104
    function GetEdge2: TDouble2D;
105
    function GetEdge3: TDouble2D;
106
    function GetEnor1: TDouble2D;
107
    function GetEnor2: TDouble2D;
108
    function GetEnor3: TDouble2D;
109
    function GetAABB: TDoubleArea2D;
110
  public
111
    Poin1: TDouble2D;
112
    Poin2: TDouble2D;
113
    Poin3: TDouble2D;
114
    property Norv: Double read GetNorv;
115
    property Edge1: TDouble2D read GetEdge1;
116
    property Edge2: TDouble2D read GetEdge2;
117
    property Edge3: TDouble2D read GetEdge3;
118
    property Enor1: TDouble2D read GetEnor1;
119
    property Enor2: TDouble2D read GetEnor2;
120
    property Enor3: TDouble2D read GetEnor3;
121
    property AABB: TDoubleArea2D read GetAABB;
122
    function ColliEdge(const Area_: TDoubleArea2D): Boolean;
123
    function Collision(const Area_: TDoubleArea2D): Boolean;
124
  end;
125

126

127
  // ---------------------------------------------------------------------------
128

129
function HeronAre2(const L1_, L2_, L3_: Single): Single; overload;
130
function HeronAre2(const L1_, L2_, L3_: Double): Double; overload;
131

132
function HeronArea(const L1_, L2_, L3_: Single): Single; overload;
133
function HeronArea(const L1_, L2_, L3_: Double): Double; overload;
134

135
function LineNormal(const P0_, P1_: TSingle2D): TSingle2D; overload;
136
function LineNormal(const P0_, P1_: TDouble2D): TDouble2D; overload;
137

138
function Barycenter(const P1_, P2_: TSinglePos2D): TSinglePos2D; overload;
139
function Barycenter(const P1_, P2_: TDoublePos2D): TDoublePos2D; overload;
140

141
function Barycenter(const P1_, P2_, P3_: TSinglePos2D): TSinglePos2D; overload;
142
function Barycenter(const P1_, P2_, P3_: TDoublePos2D): TDoublePos2D; overload;
143

144
function InnerRadius(const P1_, P2_, P3_: TSinglePos2D): Single; overload;
145
function InnerRadius(const P1_, P2_, P3_: TDoublePos2D): Double; overload;
146

147
function InnerCenter(const P1_, P2_, P3_: TSinglePos2D): TSinglePos2D; overload;
148
function InnerCenter(const P1_, P2_, P3_: TDoublePos2D): TDoublePos2D; overload;
149

150
function CircumCenter(const P1_, P2_, P3_: TSingle2D): TSingle2D; overload;
151
function CircumCenter(const P1_, P2_, P3_: TDouble2D): TDouble2D; overload;
152

153
function CurveLength(const Ps_: array of TSingle2D): Single; overload;
154
function CurveLength(const Ps_: array of TDouble2D): Single; overload;
155

156
function ClosedCurveLength(const Ps_: array of TSingle2D): Single; overload;
157
function ClosedCurveLength(const Ps_: array of TDouble2D): Single; overload;
158

159
function BoundingBox(const Ps_: array of TSingle2D): TSingleArea2D; overload;
160
function BoundingBox(const Ps_: array of TDouble2D): TDoubleArea2D; overload;
161

162
function ShapeMatch(const Vs0_, Vs1_: array of TSingle2D): TSingleM2; overload;
163
function ShapeMatch(const Vs0_, Vs1_: array of TDouble2D): TDoubleM2; overload;
164

165
function InsideLoop(const P_: TSingle2D; const Ps_: TArray<TSingle2D>)
166
  : Single; overload;
167
function InsideLoop(const P_: TDouble2D; const Ps_: TArray<TDouble2D>)
168
  : Double; overload;
169

170
implementation // -------------------------------------------------------------
171

172
constructor TSingleCircl2.Create(const P1_, P2_, P3_: TSingle2D);
173
begin
174
  Center := CircumCenter(P1_, P2_, P3_);
175
  Radiu2 := (Distanc2(Center, P1_) + Distanc2(Center, P2_) + Distanc2(Center,
176
    P3_)) / 3;
177
end;
178

179
constructor TDoubleCircl2.Create(const P1_, P2_, P3_: TDouble2D);
180
begin
181
  Center := CircumCenter(P1_, P2_, P3_);
182
  Radiu2 := (Distanc2(Center, P1_) + Distanc2(Center, P2_) + Distanc2(Center,
183
    P3_)) / 3;
184
end;
185

186
constructor TSingleCircle.Create(const P1_, P2_, P3_: TSingle2D);
187
begin
188
  Self := TSingleCircl2.Create(P1_, P2_, P3_);
189
end;
190

191
class operator TSingleCircle.Implicit(const Circl2_: TSingleCircl2)
192
  : TSingleCircle;
193
begin
194
  with Result do
195
  begin
196
    Center := Circl2_.Center;
197
    Radius := Roo2(Circl2_.Radiu2);
198
  end;
199
end;
200

201
class operator TSingleCircle.Implicit(const Circle_: TSingleCircle)
202
  : TSingleCircl2;
203
begin
204
  with Result do
205
  begin
206
    Center := Circle_.Center;
207
    Radiu2 := Pow2(Circle_.Radius);
208
  end;
209
end;
210

211
constructor TDoubleCircle.Create(const P1_, P2_, P3_: TDouble2D);
212
begin
213
  Self := TDoubleCircl2.Create(P1_, P2_, P3_);
214
end;
215

216
class operator TDoubleCircle.Implicit(const Circl2_: TDoubleCircl2)
217
  : TDoubleCircle;
218
begin
219
  with Result do
220
  begin
221
    Center := Circl2_.Center;
222
    Radius := Roo2(Circl2_.Radiu2);
223
  end;
224
end;
225

226
class operator TDoubleCircle.Implicit(const Circle_: TDoubleCircle)
227
  : TDoubleCircl2;
228
begin
229
  with Result do
230
  begin
231
    Center := Circle_.Center;
232
    Radiu2 := Pow2(Circle_.Radius);
233
  end;
234
end;
235

236
function TSingleTria2D.GetNorv: Single;
237
begin
238
  Result := CrossProduct(Edge2, Edge3);
239
end;
240

241
// ------------------------------------------------------------------------------
242

243
function TSingleTria2D.GetEdge1: TSingle2D;
244
begin
245
  Result := Poin2.VectorTo(Poin3);
246
end;
247

248
function TSingleTria2D.GetEdge2: TSingle2D;
249
begin
250
  Result := Poin3.VectorTo(Poin1);
251
end;
252

253
function TSingleTria2D.GetEdge3: TSingle2D;
254
begin
255
  Result := Poin1.VectorTo(Poin2);
256
end;
257

258
// ------------------------------------------------------------------------------
259

260
function TSingleTria2D.GetEnor1: TSingle2D;
261
begin
262
  Result := Norv * Edge1.RotL90;
263
end;
264

265
function TSingleTria2D.GetEnor2: TSingle2D;
266
begin
267
  Result := Norv * Edge2.RotL90;
268
end;
269

270
function TSingleTria2D.GetEnor3: TSingle2D;
271
begin
272
  Result := Norv * Edge3.RotL90;
273
end;
274

275
// ------------------------------------------------------------------------------
276

277
function TSingleTria2D.GetAABB: TSingleArea2D;
278
begin
279
  with Result do
280
  begin
281
    ProjX := TSingleArea.Create(Poin1.X, Poin2.X, Poin3.X);
282
    ProjY := TSingleArea.Create(Poin1.Y, Poin2.Y, Poin3.Y);
283
  end;
284
end;
285

286
// ······································
287

288
function TSingleTria2D.ColliEdge(const Area_: TSingleArea2D): Boolean;
289
  (*sub*)function CheckEdge(const N, P: TSingle2D): Boolean;
290
  var
291
    B, V: TSingle2D;
292
  begin
293
    B := Area_.Poin[N.Orthant];
294

295
    V := P.VectorTo(B);
296

297
    Result := DotProduct(N, V) >= 0;
298
  end;
299

300
// ······································
301
begin
302
  // P3
303
  // │\
304
  // │  \
305
  // │    \
306
  // E2─N2  E1
307
  // │    /  \
308
  // │  N1  N3  \
309
  // │      │    \
310
  // P1───E3───P2
311

312
  Result := CheckEdge(Enor1, Poin2) and CheckEdge(Enor2, Poin3) and
313
    CheckEdge(Enor3, Poin1);
314
end;
315

316
function TSingleTria2D.Collision(const Area_: TSingleArea2D): Boolean;
317
begin
318
  Result := AABB.Collision(Area_) and ColliEdge(Area_);
319
end;
320

321
function TDoubleTria2D.GetNorv: Double;
322
begin
323
  Result := CrossProduct(Edge2, Edge3);
324
end;
325

326
// ------------------------------------------------------------------------------
327

328
function TDoubleTria2D.GetEdge1: TDouble2D;
329
begin
330
  Result := Poin2.VectorTo(Poin3);
331
end;
332

333
function TDoubleTria2D.GetEdge2: TDouble2D;
334
begin
335
  Result := Poin3.VectorTo(Poin1);
336
end;
337

338
function TDoubleTria2D.GetEdge3: TDouble2D;
339
begin
340
  Result := Poin1.VectorTo(Poin2);
341
end;
342

343
// ------------------------------------------------------------------------------
344

345
function TDoubleTria2D.GetEnor1: TDouble2D;
346
begin
347
  Result := Norv * Edge1.RotL90;
348
end;
349

350
function TDoubleTria2D.GetEnor2: TDouble2D;
351
begin
352
  Result := Norv * Edge2.RotL90;
353
end;
354

355
function TDoubleTria2D.GetEnor3: TDouble2D;
356
begin
357
  Result := Norv * Edge3.RotL90;
358
end;
359

360
// ------------------------------------------------------------------------------
361

362
function TDoubleTria2D.GetAABB: TDoubleArea2D;
363
begin
364
  with Result do
365
  begin
366
    ProjX := TDoubleArea.Create(Poin1.X, Poin2.X, Poin3.X);
367
    ProjY := TDoubleArea.Create(Poin1.Y, Poin2.Y, Poin3.Y);
368
  end;
369
end;
370

371
// ······································
372
function TDoubleTria2D.ColliEdge(const Area_: TDoubleArea2D): Boolean;
373
  (*sub*)function CheckEdge(const N, P: TDouble2D): Boolean;
374
  var
375
    B, V: TDouble2D;
376
  begin
377
    B := Area_.Poin[N.Orthant];
378

379
    V := P.VectorTo(B);
380

381
    Result := DotProduct(N, V) >= 0;
382
  end;
383

384
// ······································
385
begin
386
  // P3
387
  // │\
388
  // │  \
389
  // │    \
390
  // E2─N2  E1
391
  // │    /  \
392
  // │  N1  N3  \
393
  // │      │    \
394
  // P1───E3───P2
395

396
  Result := CheckEdge(Enor1, Poin2) and CheckEdge(Enor2, Poin3) and
397
    CheckEdge(Enor3, Poin1);
398
end;
399

400
function TDoubleTria2D.Collision(const Area_: TDoubleArea2D): Boolean;
401
begin
402
  Result := AABB.Collision(Area_) and ColliEdge(Area_);
403
end;
404

405
function HeronAre2(const L1_, L2_, L3_: Single): Single;
406
var
407
  S: Single;
408
begin
409
  S := (L1_ + L2_ + L3_) / 2;
410

411
  Result := S * (S - L1_) * (S - L2_) * (S - L3_);
412
end;
413

414
function HeronAre2(const L1_, L2_, L3_: Double): Double;
415
var
416
  S: Double;
417
begin
418
  S := (L1_ + L2_ + L3_) / 2;
419

420
  Result := S * (S - L1_) * (S - L2_) * (S - L3_);
421
end;
422

423
// ------------------------------------------------------------------------------
424

425
function HeronArea(const L1_, L2_, L3_: Single): Single;
426
begin
427
  Result := Roo2(HeronAre2(L1_, L2_, L3_));
428
end;
429

430
function HeronArea(const L1_, L2_, L3_: Double): Double;
431
begin
432
  Result := Roo2(HeronAre2(L1_, L2_, L3_));
433
end;
434

435
// ------------------------------------------------------------------------------
436

437
function LineNormal(const P0_, P1_: TSingle2D): TSingle2D;
438
begin
439
  with P0_.VectorTo(P1_) do
440
  begin
441
    Result.X := +Y;
442
    Result.Y := -X;
443
  end;
444
end;
445

446
function LineNormal(const P0_, P1_: TDouble2D): TDouble2D;
447
begin
448
  with P0_.VectorTo(P1_) do
449
  begin
450
    Result.X := +Y;
451
    Result.Y := -X;
452
  end;
453
end;
454

455
// ------------------------------------------------------------------------------
456

457
function Barycenter(const P1_, P2_: TSinglePos2D): TSinglePos2D;
458
begin
459
  Result := Ave(P1_, P2_);
460
end;
461

462
function Barycenter(const P1_, P2_: TDoublePos2D): TDoublePos2D;
463
begin
464
  Result := Ave(P1_, P2_);
465
end;
466

467
function Barycenter(const P1_, P2_, P3_: TSinglePos2D): TSinglePos2D;
468
begin
469
  Result := Ave(P1_, P2_, P3_);
470
end;
471

472
function Barycenter(const P1_, P2_, P3_: TDoublePos2D): TDoublePos2D;
473
begin
474
  Result := Ave(P1_, P2_, P3_);
475
end;
476

477
// ------------------------------------------------------------------------------
478

479
function InnerRadius(const P1_, P2_, P3_: TSinglePos2D): Single;
480
var
481
  L1, L2, L3, S: Single;
482
begin
483
  L1 := Distance(P2_, P3_);
484
  L2 := Distance(P3_, P1_);
485
  L3 := Distance(P1_, P2_);
486

487
  S := (L1 + L2 + L3) / 2;
488

489
  Result := Roo2((S - L1) * (S - L2) * (S - L3) / S);
490
end;
491

492
function InnerRadius(const P1_, P2_, P3_: TDoublePos2D): Double;
493
var
494
  L1, L2, L3, S: Single;
495
begin
496
  L1 := Distance(P2_, P3_);
497
  L2 := Distance(P3_, P1_);
498
  L3 := Distance(P1_, P2_);
499

500
  S := (L1 + L2 + L3) / 2;
501

502
  Result := Roo2((S - L1) * (S - L2) * (S - L3) / S);
503
end;
504

505
// ------------------------------------------------------------------------------
506

507
function InnerCenter(const P1_, P2_, P3_: TSinglePos2D): TSinglePos2D;
508
var
509
  L1, L2, L3: Single;
510
begin
511
  L1 := Distance(P2_, P3_);
512
  L2 := Distance(P3_, P1_);
513
  L3 := Distance(P1_, P2_);
514

515
  Result := (L1 * P1_ + L2 * P2_ + L3 * P3_) / (L1 + L2 + L3);
516
end;
517

518
function InnerCenter(const P1_, P2_, P3_: TDoublePos2D): TDoublePos2D;
519
var
520
  L1, L2, L3: Double;
521
begin
522
  L1 := Distance(P2_, P3_);
523
  L2 := Distance(P3_, P1_);
524
  L3 := Distance(P1_, P2_);
525

526
  Result := (L1 * P1_ + L2 * P2_ + L3 * P3_) / (L1 + L2 + L3);
527
end;
528

529
// ------------------------------------------------------------------------------
530

531
function CircumCenter(const P1_, P2_, P3_: TSingle2D): TSingle2D;
532
var
533
  L1, L2, L3, W: Single;
534
  E1, E2, E3: TSingle2D;
535
begin
536
  L1 := P1_.Siz2;
537
  E1 := P3_ - P2_;
538
  L2 := P2_.Siz2;
539
  E2 := P1_ - P3_;
540
  L3 := P3_.Siz2;
541
  E3 := P2_ - P1_;
542

543
  W := 2 * (P2_.X * P1_.Y - P1_.X * P2_.Y + P3_.X * P2_.Y - P2_.X * P3_.Y +
544
    P1_.X * P3_.Y - P3_.X * P1_.Y);
545

546
  with Result do
547
  begin
548
    X := (L1 * E1.Y + L2 * E2.Y + L3 * E3.Y) / +W;
549
    Y := (L1 * E1.X + L2 * E2.X + L3 * E3.X) / -W;
550
  end;
551
end;
552

553
function CircumCenter(const P1_, P2_, P3_: TDouble2D): TDouble2D;
554
var
555
  L1, L2, L3, W: Double;
556
  E1, E2, E3: TDouble2D;
557
begin
558
  L1 := P1_.Siz2;
559
  E1 := P3_ - P2_;
560
  L2 := P2_.Siz2;
561
  E2 := P1_ - P3_;
562
  L3 := P3_.Siz2;
563
  E3 := P2_ - P1_;
564

565
  W := 2 * (P2_.X * P1_.Y - P1_.X * P2_.Y + P3_.X * P2_.Y - P2_.X * P3_.Y +
566
    P1_.X * P3_.Y - P3_.X * P1_.Y);
567

568
  with Result do
569
  begin
570
    X := (L1 * E1.Y + L2 * E2.Y + L3 * E3.Y) / +W;
571
    Y := (L1 * E1.X + L2 * E2.X + L3 * E3.X) / -W;
572
  end;
573
end;
574

575
// ------------------------------------------------------------------------------
576

577
function CurveLength(const Ps_: array of TSingle2D): Single;
578
var
579
  I: Integer;
580
  P0, P1: TSingle2D;
581
begin
582
  Result := 0;
583

584
  P1 := Ps_[0];
585
  for I := 1 to High(Ps_) do
586
  begin
587
    P0 := P1;
588
    P1 := Ps_[I];
589

590
    Result := Result + Distance(P0, P1);
591
  end;
592
end;
593

594
function CurveLength(const Ps_: array of TDouble2D): Single;
595
var
596
  I: Integer;
597
  P0, P1: TDouble2D;
598
begin
599
  Result := 0;
600

601
  P1 := Ps_[0];
602
  for I := 1 to High(Ps_) do
603
  begin
604
    P0 := P1;
605
    P1 := Ps_[I];
606

607
    Result := Result + Distance(P0, P1);
608
  end;
609
end;
610

611
// ------------------------------------------------------------------------------
612

613
function ClosedCurveLength(const Ps_: array of TSingle2D): Single;
614
var
615
  I: Integer;
616
  P0, P1, P2: TSingle2D;
617
begin
618
  Result := 0;
619

620
  P2 := Ps_[0];
621

622
  P1 := P2;
623
  for I := 1 to High(Ps_) do
624
  begin
625
    P0 := P1;
626
    P1 := Ps_[I];
627

628
    Result := Result + Distance(P0, P1);
629
  end;
630

631
  Result := Result + Distance(P1, P2);
632
end;
633

634
function ClosedCurveLength(const Ps_: array of TDouble2D): Single;
635
var
636
  I: Integer;
637
  P0, P1, P2: TDouble2D;
638
begin
639
  Result := 0;
640

641
  P2 := Ps_[0];
642

643
  P1 := P2;
644
  for I := 1 to High(Ps_) do
645
  begin
646
    P0 := P1;
647
    P1 := Ps_[I];
648

649
    Result := Result + Distance(P0, P1);
650
  end;
651

652
  Result := Result + Distance(P1, P2);
653
end;
654

655
// ------------------------------------------------------------------------------
656

657
function BoundingBox(const Ps_: array of TSingle2D): TSingleArea2D;
658
var
659
  P: TSingle2D;
660
begin
661
  Result := TSingleArea2D.NeInf;
662

663
  for P in Ps_ do
664
  begin
665
    if P.X < Result.Min.X then
666
      Result.Min.X := P.X;
667
    if P.Y < Result.Min.Y then
668
      Result.Min.Y := P.Y;
669

670
    if Result.Max.X < P.X then
671
      Result.Max.X := P.X;
672
    if Result.Max.Y < P.Y then
673
      Result.Max.Y := P.Y;
674
  end;
675
end;
676

677
function BoundingBox(const Ps_: array of TDouble2D): TDoubleArea2D;
678
var
679
  P: TDouble2D;
680
begin
681
  Result := TDoubleArea2D.NeInf;
682

683
  for P in Ps_ do
684
  begin
685
    if P.X < Result.Min.X then
686
      Result.Min.X := P.X;
687
    if P.Y < Result.Min.Y then
688
      Result.Min.Y := P.Y;
689

690
    if Result.Max.X < P.X then
691
      Result.Max.X := P.X;
692
    if Result.Max.Y < P.Y then
693
      Result.Max.Y := P.Y;
694
  end;
695
end;
696

697
// ------------------------------------------------------------------------------
698

699
function ShapeMatch(const Vs0_, Vs1_: array of TSingle2D): TSingleM2;
700
var
701
  I: Integer;
702
  V0, V1: TSingle2D;
703
  M: TSingleM2;
704
begin
705
  Result := TSingleM2.Create(0, 0, 0, 0);
706

707
  for I := 0 to High(Vs0_) do
708
  begin
709
    V0 := Vs0_[I];
710
    V1 := Vs1_[I];
711

712
    with M do
713
    begin
714
      _11 := V1.X * V0.X + V1.Y * V0.Y;
715
      _12 := V1.X * V0.Y - V1.Y * V0.X;
716
      _21 := V1.Y * V0.X - V1.X * V0.Y;
717
      _22 := V1.X * V0.X + V1.Y * V0.Y;
718
    end;
719

720
    Result := Result + M;
721
  end;
722

723
  Result := Result / Roo2(Pow2(Result._11) + Pow2(Result._12));
724
end;
725

726
function ShapeMatch(const Vs0_, Vs1_: array of TDouble2D): TDoubleM2;
727
var
728
  I: Integer;
729
  V0, V1: TDouble2D;
730
  M: TDoubleM2;
731
begin
732
  Result := TDoubleM2.Create(0, 0, 0, 0);
733

734
  for I := 0 to High(Vs0_) do
735
  begin
736
    V0 := Vs0_[I];
737
    V1 := Vs1_[I];
738

739
    with M do
740
    begin
741
      _11 := V1.X * V0.X + V1.Y * V0.Y;
742
      _12 := V1.X * V0.Y - V1.Y * V0.X;
743
      _21 := V1.Y * V0.X - V1.X * V0.Y;
744
      _22 := V1.X * V0.X + V1.Y * V0.Y;
745
    end;
746

747
    Result := Result + M;
748
  end;
749

750
  Result := Result / Roo2(Pow2(Result._11) + Pow2(Result._12));
751
end;
752

753
// ------------------------------------------------------------------------------
754

755
function InsideLoop(const P_: TSingle2D; const Ps_: TArray<TSingle2D>): Single;
756
var
757
  I: Integer;
758
  P0, P1, P2, V0, V1: TSingle2D;
759
  A: Single;
760
begin
761
  Result := 0;
762

763
  P2 := Ps_[0];
764
  P1 := P2;
765
  for I := 1 to High(Ps_) - 1 do
766
  begin
767
    P0 := P1;
768
    P1 := Ps_[I];
769

770
    V0 := P0 - P_;
771
    V1 := P1 - P_;
772

773
    A := V0.RotAngleTo(V1);
774

775
    Result := Result + A;
776
  end;
777

778
  V0 := P1 - P_;
779
  V1 := P2 - P_;
780

781
  A := V0.RotAngleTo(V1);
782

783
  Result := Result + A;
784

785
  Result := Result / Pi2;
786
end;
787

788
function InsideLoop(const P_: TDouble2D; const Ps_: TArray<TDouble2D>): Double;
789
var
790
  I: Integer;
791
  P0, P1, P2, V0, V1: TDouble2D;
792
  A: Double;
793
begin
794
  Result := 0;
795

796
  P2 := Ps_[0];
797
  P1 := P2;
798
  for I := 1 to High(Ps_) - 1 do
799
  begin
800
    P0 := P1;
801
    P1 := Ps_[I];
802

803
    V0 := P0 - P_;
804
    V1 := P1 - P_;
805

806
    A := V0.RotAngleTo(V1);
807

808
    Result := Result + A;
809
  end;
810

811
  V0 := P1 - P_;
812
  V1 := P2 - P_;
813

814
  A := V0.RotAngleTo(V1);
815

816
  Result := Result + A;
817

818
  Result := Result / Pi2;
819
end;
820

821
initialization //------------------------------------------------------------
822

823
finalization
824

825
end.
826

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.