Advertisement
WarPie90

Complex curved line

Apr 12th, 2022 (edited)
797
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 3.78 KB | None | 0 0
  1. program new;
  2.  
  3. var
  4.   BMP: TImage;
  5.  
  6. type
  7.   Vector2 = record x,y: Single; end;
  8.  
  9. function Vector2.ToPoint(): TPoint;
  10. begin
  11.   Result := [Round(Self.x), Round(Self.y)];
  12. end;
  13.  
  14. function GenSubPoints(A,B:Vector2; count: Int32): array of Vector2;
  15. var
  16.   t,d,r,rx,ry,step: Double;
  17.   i,j,k: Int32;
  18.   vec: Vector2;
  19.   v,tmp: array of Vector2;
  20. begin
  21.   if count = 0 then Exit([A,B]);
  22.   d := Hypot(A.x-B.x, B.y-B.y) / count;
  23.   SetLength(v, count);
  24.   v[0] := A;
  25.  
  26.   r := d*RandomMean(-0.75,0.75);
  27.   for i:=1 to count-1 do
  28.   begin
  29.     t := RandomMode(0.5,-1.0,1.5);
  30.     v[i].x := (1 - t) * v[i - 1].x + t * B.x + r;
  31.     v[i].y := (1 - t) * v[i - 1].y + t * B.y + r;
  32.   end;
  33.   v[count-1] := B;
  34.  
  35.   step := Max(0.01, 1/Sqr(count));
  36.   t := 0;
  37.   while t <= 1 do
  38.   begin
  39.     tmp := Copy(v);
  40.     for i:=High(tmp) downto 1 do
  41.       for k:=0 to i-1 do
  42.       begin
  43.         tmp[k].x := tmp[k].x + (tmp[k+1].x - tmp[k].x) * t;
  44.         tmp[k].y := tmp[k].y + (tmp[k+1].y - tmp[k].y) * t;
  45.       end;
  46.     vec := tmp[0];
  47.     Result += vec;
  48.     t += step;
  49.   end;
  50.   Result += B;
  51. end;
  52.  
  53.  
  54. function SmoothLine(src, dst: Vector2; Gravity, NoiseLevel, maxStep: Double; Sharpness:Int32; targetArea:Double): TPointArray;
  55. var
  56.   t,noiseX,noiseY,dist,xstep,ystep,len,newDist,rmaxStep,rNoise,rGravity: Single;
  57.   i: Int32;
  58.   prev,tmp: TPoint;
  59.   line: TPointArray;
  60.   v: array of Vector2;
  61. const
  62.   PI2 := PI/2;
  63. begin
  64.   v := GenSubPoints(src,dst, sharpness);
  65.   //for i:=0 to High(v) do
  66.   //  BMP.DrawCircle(v[i].ToPoint, 3);
  67.  
  68.   noiseX := Random();
  69.   noiseY := Random();
  70.  
  71.   Result += src.ToPoint;
  72.   prev := src.ToPoint;
  73.  
  74.   rMaxStep := maxStep;
  75.   rNoise   := NoiseLevel;
  76.   rGravity := Gravity;
  77.  
  78.   i := 1;
  79.   dst := v[i];
  80.   dist := Hypot(src.x - dst.x, src.y - dst.y);
  81.   while (Hypot(src.x - v[High(v)].x, src.y - v[High(v)].y) > 1) do
  82.   begin
  83.     if (dist < targetArea) then
  84.     begin
  85.       if (i = High(v)) then
  86.       begin
  87.         if (rMaxStep > 1) then rMaxStep /= SQRT_2;
  88.       end else
  89.       begin
  90.         dst := v[Inc(i)];
  91.         rMaxStep := Max(SQRT_2, Min(MaxStep, Hypot(src.x - v[i].x, src.y - v[i].y)));
  92.  
  93.         if rMaxStep >= SQRT_5 then
  94.         begin
  95.           rNoise   := NoiseLevel;
  96.           rGravity := Gravity;
  97.         end else
  98.         begin
  99.           rNoise := 0;
  100.           rGravity := 1;
  101.         end;
  102.       end;
  103.     end;
  104.  
  105.     noiseX := noiseX * 2/3 + (2*Random()-1) * rNoise * 1/3;
  106.     noiseY := noiseY * 2/3 + (2*Random()-1) * rNoise * 1/3;
  107.     xstep := noiseX + rGravity * (dst.x-src.x) / dist;
  108.     ystep := noiseY + rGravity * (dst.y-src.y) / dist;
  109.     len := Hypot(xstep, ystep);
  110.  
  111.     if (len > rMaxStep) then
  112.     begin
  113.       newDist := 1+Random() * rMaxStep;
  114.       xstep := (xstep / len) * newDist;
  115.       ystep := (ystep / len) * newDist;
  116.     end;
  117.  
  118.     src.x += xstep;
  119.     src.y += ystep;
  120.     tmp.x := Round(src.x);
  121.     tmp.y := Round(src.y);
  122.  
  123.     if (tmp <> prev) then
  124.     begin
  125.       if len <= SQRT_2 then
  126.         result += tmp
  127.       else
  128.       begin
  129.         //line := TPointArray.CreateFromLine(prev, tmp);
  130.         result += tmp;//line;
  131.       end;
  132.     end;
  133.  
  134.     dist := Hypot(src.x - dst.x, src.y - dst.y);
  135.     prev := tmp;
  136.   end;
  137. end;
  138.  
  139.  
  140. var
  141.   p,q: TPoint;
  142.   a: TPoint=[50,150];
  143.   b: TPoint=[600,150];
  144.   i,c: Int32;
  145. begin
  146.   bmp := TImage.Create(700,700);
  147.   bmp.Show();
  148.  
  149.   while True do
  150.   begin
  151.     bmp.DrawColor := Random($FFFFFF);
  152.     bmp.Clear();
  153.  
  154.     q := a;
  155.     for p in SmoothLine([a.x,a.y], [b.x,b.y], 7, 2.5, 10, 7, 40) do
  156.     try
  157.       if InRange(p.x, 0,bmp.Width-1) and InRange(p.y, 0,bmp.Height-1) then
  158.         bmp.DrawLineAA(q,p,2);
  159.  
  160.       q := p;
  161.       Inc(i);
  162.  
  163.  
  164.       DebugImageUpdate(bmp);
  165.     except end;
  166.  
  167.     //a.y += 20;
  168.     //b.y += 20;
  169.  
  170.     //DebugImageUpdate(bmp);
  171.     //Sleep(500);
  172.   end;
  173.   bmp.Show(False);
  174. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement