Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- program new;
- var
- BMP: TImage;
- type
- Vector2 = record x,y: Single; end;
- function Vector2.ToPoint(): TPoint;
- begin
- Result := [Round(Self.x), Round(Self.y)];
- end;
- function GenSubPoints(A,B:Vector2; count: Int32): array of Vector2;
- var
- t,d,r,rx,ry,step: Double;
- i,j,k: Int32;
- vec: Vector2;
- v,tmp: array of Vector2;
- begin
- if count = 0 then Exit([A,B]);
- d := Hypot(A.x-B.x, B.y-B.y) / count;
- SetLength(v, count);
- v[0] := A;
- r := d*RandomMean(-0.75,0.75);
- for i:=1 to count-1 do
- begin
- t := RandomMode(0.5,-1.0,1.5);
- v[i].x := (1 - t) * v[i - 1].x + t * B.x + r;
- v[i].y := (1 - t) * v[i - 1].y + t * B.y + r;
- end;
- v[count-1] := B;
- step := Max(0.01, 1/Sqr(count));
- t := 0;
- while t <= 1 do
- begin
- tmp := Copy(v);
- for i:=High(tmp) downto 1 do
- for k:=0 to i-1 do
- begin
- tmp[k].x := tmp[k].x + (tmp[k+1].x - tmp[k].x) * t;
- tmp[k].y := tmp[k].y + (tmp[k+1].y - tmp[k].y) * t;
- end;
- vec := tmp[0];
- Result += vec;
- t += step;
- end;
- Result += B;
- end;
- function SmoothLine(src, dst: Vector2; Gravity, NoiseLevel, maxStep: Double; Sharpness:Int32; targetArea:Double): TPointArray;
- var
- t,noiseX,noiseY,dist,xstep,ystep,len,newDist,rmaxStep,rNoise,rGravity: Single;
- i: Int32;
- prev,tmp: TPoint;
- line: TPointArray;
- v: array of Vector2;
- const
- PI2 := PI/2;
- begin
- v := GenSubPoints(src,dst, sharpness);
- //for i:=0 to High(v) do
- // BMP.DrawCircle(v[i].ToPoint, 3);
- noiseX := Random();
- noiseY := Random();
- Result += src.ToPoint;
- prev := src.ToPoint;
- rMaxStep := maxStep;
- rNoise := NoiseLevel;
- rGravity := Gravity;
- i := 1;
- dst := v[i];
- dist := Hypot(src.x - dst.x, src.y - dst.y);
- while (Hypot(src.x - v[High(v)].x, src.y - v[High(v)].y) > 1) do
- begin
- if (dist < targetArea) then
- begin
- if (i = High(v)) then
- begin
- if (rMaxStep > 1) then rMaxStep /= SQRT_2;
- end else
- begin
- dst := v[Inc(i)];
- rMaxStep := Max(SQRT_2, Min(MaxStep, Hypot(src.x - v[i].x, src.y - v[i].y)));
- if rMaxStep >= SQRT_5 then
- begin
- rNoise := NoiseLevel;
- rGravity := Gravity;
- end else
- begin
- rNoise := 0;
- rGravity := 1;
- end;
- end;
- end;
- noiseX := noiseX * 2/3 + (2*Random()-1) * rNoise * 1/3;
- noiseY := noiseY * 2/3 + (2*Random()-1) * rNoise * 1/3;
- xstep := noiseX + rGravity * (dst.x-src.x) / dist;
- ystep := noiseY + rGravity * (dst.y-src.y) / dist;
- len := Hypot(xstep, ystep);
- if (len > rMaxStep) then
- begin
- newDist := 1+Random() * rMaxStep;
- xstep := (xstep / len) * newDist;
- ystep := (ystep / len) * newDist;
- end;
- src.x += xstep;
- src.y += ystep;
- tmp.x := Round(src.x);
- tmp.y := Round(src.y);
- if (tmp <> prev) then
- begin
- if len <= SQRT_2 then
- result += tmp
- else
- begin
- //line := TPointArray.CreateFromLine(prev, tmp);
- result += tmp;//line;
- end;
- end;
- dist := Hypot(src.x - dst.x, src.y - dst.y);
- prev := tmp;
- end;
- end;
- var
- p,q: TPoint;
- a: TPoint=[50,150];
- b: TPoint=[600,150];
- i,c: Int32;
- begin
- bmp := TImage.Create(700,700);
- bmp.Show();
- while True do
- begin
- bmp.DrawColor := Random($FFFFFF);
- bmp.Clear();
- q := a;
- for p in SmoothLine([a.x,a.y], [b.x,b.y], 7, 2.5, 10, 7, 40) do
- try
- if InRange(p.x, 0,bmp.Width-1) and InRange(p.y, 0,bmp.Height-1) then
- bmp.DrawLineAA(q,p,2);
- q := p;
- Inc(i);
- DebugImageUpdate(bmp);
- except end;
- //a.y += 20;
- //b.y += 20;
- //DebugImageUpdate(bmp);
- //Sleep(500);
- end;
- bmp.Show(False);
- end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement