Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // original work at this pastebin - with description:
- // https://pastebin.com/7N2iuDsF
- type
- TTriangle = record A,B,C: TPoint; end;
- function TTriangle.Contains(P: TPoint): Boolean; constref;
- var
- c1, c2, c3: Int32;
- begin
- c1 := Sign(srl.CrossProduct(A, B, P));
- c2 := srl.CrossProduct(B, C, P);
- c3 := srl.CrossProduct(C, A, P);
- Result := (c1 * c2 >= 0) and (c1 * c3 >= 0) and (Sign(c2) * c3 >= 0);
- end;
- function TTriangle.NearestEdge(P: TPoint): TPoint; constref;
- var
- Best, Dist: Single;
- X: TPoint;
- begin
- Best := srl.DistToLineEx(P, Self.A, Self.B, Result);
- if (dist := srl.DistToLineEx(P, Self.B, Self.C, X)) < Best then begin Result := X; Best := Dist; end;
- if (dist := srl.DistToLineEx(P, Self.C, Self.A, X)) < Best then Result := X;
- end;
- function TTriangle.RandomWeightedPoint(Target: TPoint; weight: Single=10.0; bias: Single=1): TPoint; constref;
- var
- r1, r2, r3, u, v, w, t, sum: Single;
- stdev,xr,yr: Single;
- const
- eps := 0.0000001;
- begin
- if bias > 0 then
- begin
- xr := abs(Self.A.x - Target.x) + abs(Self.B.x - Target.x) + abs(Self.C.x - Target.x);
- yr := abs(Self.A.y - Target.y) + abs(Self.B.y - Target.y) + abs(Self.C.y - Target.y);
- Target.X += Round(srl.GaussRand(0, xr/3 * bias) / weight);
- Target.Y += Round(srl.GaussRand(0, yr/3 * bias) / weight);
- end;
- if not Self.Contains(Target) then
- Target := Self.NearestEdge(Target);
- r1 := Random();
- r2 := Random();
- if r1 + r2 > 1 then
- begin
- r1 := 1 - r1;
- r2 := 1 - r2;
- end;
- r3 := Random();
- sum := 1 + weight * r3 + eps;
- u := r1 / sum;
- v := r2 / sum;
- w := (1 - r1 - r2) / sum;
- t := (weight * r3) / sum;
- with Self do
- begin
- Result.X := Round(u * A.X + v * B.X + w * C.X + t * Target.X);
- Result.Y := Round(u * A.Y + v * B.Y + w * C.Y + t * Target.Y);
- end;
- end;
- function ArcToTriangle(start, stop: TPoint; radians: single): TTriangle;
- begin
- Result.A := start;
- Result.B := stop.Rotate(-radians / 2, start);
- Result.C := stop.Rotate(+radians / 2, start);
- end;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement