Recent

Author Topic: Spiral: Proper Fills and Add Arcs on each end  (Read 915 times)

Boleeman

  • Sr. Member
  • ****
  • Posts: 471
Spiral: Proper Fills and Add Arcs on each end
« on: April 09, 2024, 11:22:42 am »
Been working on filling some spirals with colors and making their ends round with arcs (as shown in the attached picture)

Can't seem to get the fill to work just between the red lines with random colors. Always have  a bigger snail like shape filled on top that obscures the other spiral sections.

The CSharp Helper site has something similar , but I could not work out how Mr Stevens did it. His spiral ends all line up.
My spiral ends are radially spaced. Attached is his csharp version picture. Also, as the form is resized the number of spirals increase dynamically.

Here is my code so far:

Code: Pascal  [Select][+][-]
  1.  unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls,
  9.   Spin;
  10.  
  11. type
  12.  
  13.   { TForm1 }
  14.  
  15.   TForm1 = class(TForm)
  16.     chkDirection: TCheckBox;
  17.     PaintBox1: TPaintBox;
  18.     Panel1: TPanel;
  19.     seAValue: TSpinEdit;
  20.     seNumSpirals: TSpinEdit;
  21.     procedure chkDirectionChange(Sender: TObject);
  22.     procedure PaintBox1Paint(Sender: TObject);
  23.     procedure seAValueChange(Sender: TObject);
  24.     procedure seNumSpiralsChange(Sender: TObject);
  25.   private
  26.     SpiralBrushes: array of TBrush;
  27.     function Distance(point1, point2: TPoint): Single;
  28.     procedure DrawSpirals(ACanvas: TCanvas; center: TPoint; A: Single; num_spirals: Integer; rect: TRect);
  29.     procedure PolarToCartesian(r, theta: Single; out x, y: Single);
  30.   public
  31.  
  32.   end;
  33.  
  34. var
  35.   Form1: TForm1;
  36.  
  37. implementation
  38.  
  39. {$R *.lfm}
  40.  
  41.  
  42. procedure TForm1.PaintBox1Paint(Sender: TObject);
  43. begin
  44.   DrawSpirals(PaintBox1.Canvas, Point(PaintBox1.Width div 2, PaintBox1.Height div 2), seAValue.Value, seNumSpirals.Value, PaintBox1.ClientRect);
  45. end;
  46.  
  47. procedure TForm1.chkDirectionChange(Sender: TObject);
  48. begin
  49.       PaintBox1.Invalidate;
  50. end;
  51.  
  52. procedure TForm1.seAValueChange(Sender: TObject);
  53. begin
  54.     PaintBox1.Invalidate;
  55. end;
  56.  
  57. procedure TForm1.seNumSpiralsChange(Sender: TObject);
  58. begin
  59.     PaintBox1.Invalidate;
  60. end;
  61.  
  62. procedure TForm1.DrawSpirals(ACanvas: TCanvas; center: TPoint; A: Single; num_spirals: Integer; rect: TRect);
  63. var
  64.   i: Integer;
  65.   d_start, start_angle, max_dist, max_theta, theta, r, x, y: Single;
  66.   points: array of TPoint;
  67.   rectCenter: TPoint;
  68. begin
  69.   ACanvas.Clear;
  70.   ACanvas.Pen.Color := clBlack;
  71.   ACanvas.Brush.Style := bsClear;
  72.  
  73.   d_start := 2 * Pi / num_spirals;
  74.   start_angle := 0;
  75.   max_theta := max_dist / A + 2 * Pi;
  76.  
  77.   SetLength(points, 0);
  78.   for i := 1 to num_spirals do
  79.   begin
  80.     theta := 0;
  81.     SetLength(points, 0);
  82.     while theta <= max_theta do
  83.     begin
  84.       r := A * theta;
  85.       PolarToCartesian(r, theta + start_angle, x, y);
  86.       x += center.X;
  87.       y := center.Y + y;
  88.       SetLength(points, Length(points) + 1);
  89.       points[High(points)] := Point(Trunc(x), Trunc(y));
  90.       theta += Pi / 36; // 5 degrees
  91.     end;
  92.     ACanvas.Pen.Color := clRed; // Set pen color to red for curved spiral lines
  93.     ACanvas.Polyline(points); // Draw radial lines
  94.     start_angle += d_start;
  95.  
  96.     ACanvas.Pen.Color := clBlue; // Set pen color to blue
  97.     ACanvas.MoveTo(Round(center.X + (points[High(points)].X - center.X) * (num_spirals - 1) / num_spirals), Round(center.Y + (points[High(points)].Y - center.Y) * (num_spirals - 1) / num_spirals)); // Move pen to three-quarters of the distance from the center to the end of the radial line
  98.     ACanvas.LineTo(points[High(points)].X, points[High(points)].Y); // Draw line to end of the radial line
  99.   end;
  100. end;
  101.  
  102. function TForm1.Distance(point1, point2: TPoint): Single;
  103. var
  104.   dx, dy: Single;
  105. begin
  106.   dx := point1.X - point2.X;
  107.   dy := point1.Y - point2.Y;
  108.   Result := Sqrt(dx * dx + dy * dy);
  109. end;
  110.  
  111. procedure TForm1.PolarToCartesian(r, theta: Single; out x, y: Single);
  112. begin
  113.   x := r * Cos(theta);
  114.   y := r * Sin(theta);
  115. end;
  116.  
  117. end.
  118.  
  119.  
  120. end.
« Last Edit: April 09, 2024, 12:29:52 pm by Boleeman »

 

TinyPortal © 2005-2018