WarPie90

Complex curved line

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