Board index » delphi » Figuring the intersection of a line

Figuring the intersection of a line

Forgive my .NET references here, but I'm using .NET's "GDI+" in a project
and seeing the great help I've gotten on the Delphi boards (and the little
help
I find on the MS boards), I figured I'd pose my question here:

I'm using a .NET Graphics object (similar to a TCanvas) to draw some lines
on a UserControl and I want to figure out when a user clicks on the control,
if they've clicked on one of the painted lines. In the simplest of cases,
I'm
calling Graphics.DrawLine between two points (akin to LineTo()), so I guess
I need some sort of algorithm that can see if a point is an "intersection"
between two other points. Also, to make things more complex, I'm calling
Graphics.DrawCurve, so it's a "curve" that would probably be even
more complex to figure out if the user clicked on the line or not...

-BKN

 

Re:Figuring the intersection of a line


Hello Bryce,
I do not use .NET but there has to be something like paths and regions there
two, especially when using GDI+.
I have appended some Delphi-code that detects a line using regions. This
code is also applicable to
curves.
However when using Curves you will have to substract the inner part with
CombineRgn,
else your HitTest will also return true when inside the curve.

General:
=====
 Everything drawn on a DC between BeginPath and EndPath
can be converted to a region with PathToRegion.
With the obtained region you can make a hit test using PtInRegion.
This way you know if a point belongs to a geometric object or not.

If you have several lines crossing you will also have to save somewhere
which one is at the highest position (= the last drawn).
So when a point is in RgnLine1 and in RgnLine2, you should activate Line2 as
it was drawn on top of Line1.

Also look in the Windows API for more details about Regions and Paths.

Hope this helps.
Regards Ma?l.

CODE
=====
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Label1: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormPaint(Sender: TObject);
    procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
  private
    Rgn: HRGN;
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  BeginPath(Canvas.Handle);
    Canvas.Pen.Width := 4;
    Canvas.MoveTo(0, 0);
    Canvas.LineTo(100, 100);
  EndPath(Canvas.Handle);
  // if you do not use WidenPath then the Region will
  // not use Pen.Width and the resulting region will be to small
  WidenPath(Canvas.Handle);
  Rgn := PathToRegion(Canvas.Handle);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  DeleteObject(Rgn);
end;

procedure TForm1.FormPaint(Sender: TObject);
begin
  Canvas.Pen.Width := 4;
  Canvas.MoveTo(0, 0);
  Canvas.LineTo(100, 100);
end;

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
const
  BoolStr: array[Boolean] of string = ('False', 'True');
begin
  Label1.Caption := BoolStr[PtInRegion(Rgn, X, Y)];
end;

end.

Re:Figuring the intersection of a line


http://www.simdesign.nl/tips/tip001.html

Kind regards, Nils

"Bryce K. Nielsen" <br...@sysonyx.com> wrote in message
news:3efbd4e3@newsgroups.borland.com...

Quote
> Forgive my .NET references here, but I'm using .NET's "GDI+" in a project
> and seeing the great help I've gotten on the Delphi boards (and the little
> help
> I find on the MS boards), I figured I'd pose my question here:

> I'm using a .NET Graphics object (similar to a TCanvas) to draw some lines
> on a UserControl and I want to figure out when a user clicks on the
control,
> if they've clicked on one of the painted lines. In the simplest of cases,
> I'm
> calling Graphics.DrawLine between two points (akin to LineTo()), so I
guess
> I need some sort of algorithm that can see if a point is an "intersection"
> between two other points. Also, to make things more complex, I'm calling
> Graphics.DrawCurve, so it's a "curve" that would probably be even
> more complex to figure out if the user clicked on the line or not...

> -BKN

Other Threads