Home > Enterprise >  how can I create a custom draw line in delphi
how can I create a custom draw line in delphi

Time:06-12

I would like to draw a line on my canvas in my delphi app but need it to be a line of ****** how can I create a custom line with the * char instead of dashes or dots.

CodePudding user response:

A line has an equation having the form: Y = A * X B

A is the slope and B the offset at the origin.

If you want to draw a line from point (X1, Y1) to point (X2, Y2), you have first to determine the A and B constants of the equation:

A = (Y2 - Y1) / (X2 - X1)

Once you have A, compute B as :

B = Y1 - A * X1

Now you have A and B, you can use it to compute the intermediate points between X1 and X2. A simple loop will do. Increment X by the value you want to have you * separated.

Note: If Y2 - Y1 is greater than X2 - X1, you must iterate Y instead of X.

As an excercise, I let you write the code...

CodePudding user response:

I would use a parametric representation of the line, parameter being the line length so far drawn. This way one can draw vertical lines, and can achieve that the stars are drawn with the same distance, independent of the slope of the line.

To be more precise: To draw a line from point A to point B, compute the length of the line L, then the unit vector Dir of the direction of the line. The formula for a point P on the line is then P = A t*Dir, where t runs from 0 to L. (This is pseudo-code to be read as vector notation.)

Here is a simple routine which does this.

procedure DrawStarAt(P: TPointF; Radius: Single; aCanvas: TCanvas);
begin
  var
  r := RectF(P.X - Radius, P.Y - Radius, P.X   Radius, P.Y   Radius);
  aCanvas.FillText(r, '*', false, 1, [], TTextAlign.Center, TTextAlign.Center);
end;

procedure DrawStarLine(A, B: TPointF; aCanvas: TCanvas);
var
  // line length
  L,
  // line parameter
  t,
  // step for t
  dt,
  // Radius of the text rectangle
  Radius: Single;

  // Point to be drawn
  P,
  // unit vector for line direction
  Direction: TPointF;
  n: integer;
begin
  aCanvas.BeginScene;
  aCanvas.Fill.Color := TAlphaColorRec.Black;
  Radius := aCanvas.TextWidth('*');
  L := sqrt(sqr(B.X - A.X)   sqr(B.Y - A.Y));
  n:=trunc(L/Radius);
  //adjust dt so the last star is drawn exactly at B
  dt:=L/n;
  if L = 0 then
  begin
    DrawStarAt(A, Radius, aCanvas);
    aCanvas.EndScene;
    exit;
  end;
  Direction := PointF((B.X - A.X) / L, (B.Y - A.Y) / L);
  t := 0;
  while t < L do
  begin
    P := PointF(A.X   t * Direction.X, A.Y   t * Direction.Y);
    DrawStarAt(P, Radius, aCanvas);
    t := t   dt;
  end;
  DrawStarAt(B, Radius, aCanvas);
  aCanvas.EndScene;
end;
  • Related