Solved

Get closest value?

Posted on 1998-09-05
12
297 Views
Last Modified: 2010-04-04
I have a map and its build where i have
some mapblocks that holds Image,size,x,y and more
and when i press form i get my MouseX,MouseY
and now i need to get what Block im closest to:
if i have blocks with values: 1,14,23,99 and i have value
15 how do i get what block im closest to? becuse a case of would suck..

0
Comment
Question by:brainware
  • 5
  • 4
  • 3
12 Comments
 
LVL 3

Expert Comment

by:mirek071497
ID: 1338669
Hmmm - this is bigger problem than you probably think.
I was write some years ago map program and I have the same problem.
I was resolve this in that way :
1.first I made a list of polygons which contains the block.
2.if list is niil then I return the polygon which contain line which is nearest to my point.
3. if list is not nill than I was mady some different algorithm which depends on the additional layer parameters, however in global idea you must find the polygon which countain the nearest line to your point.

The problem is however bigger - why ? ok
You probably have big map and you can't compare to each line !
I was solve this by deviding the whole map to smalest squares and I first finding square for my point and then from list of objects which is assigned to the square I was create the search described later.
0
 
LVL 3

Accepted Solution

by:
mirek071497 earned 20 total points
ID: 1338670
Ohh - mayby you need only the algorithm which say what line is the nearest ?
so no easiest question ! ;)

look here.
You have line segment from point A1(ax1,ay1) to point B1(bx1,bx2)
first you must find the line for this points.
I think so you can use line equation like this :
y := a1*x+b1

so you must compute the a1 and b1

a1 := (by1-ay1)/(bx1-ax1)
b1 := ay1 - ax1*(by1-ay1)/(bx1-ax1)

now you must find line which is perpendicular to this one. Ok this line is :

y := -a1*x +b2

You don't know the b2, but the line need to go throught your point X1,Y1

so you can compute the b2 and :

b2 := Y1+a1*X1

now you must find the point of intersection of this lines. Nothing easiest.You must find Point X0,Y0 which is in both lines.
so you have

X0 := (X1-b1+Y1*a1)/(2*a1)
Y0 := (X1-b1+Y1*a1)/2 + b1

ok now we have 2 examples
1. the point X0.Y0 is on the line segment
2. the point X0.Y0 is outside the line segment

we must know at which example we are so you can easy check this, but for easiest way we can make an assumption so the ax1<bx1 and if not than you can check this on start of proc and than exchange points
In this assumption we have :

if (X0>ax1) and (X0<ax2) then point1 else point2;

so for point1 we need to calculate the length of the line segment from point X1,Y1 to point X0,Y0

the leght is l:= Sqrt((X1-X0)*(X1-X0)+(Y1-Y0)*(Y1-Y0));

for the second point2 we need calculate the distance between point X1.Y1 and points A1 and B1 and get the lowest value

so :
l1 := Sqrt((X1-ax1)*(X1-ax1)+(Y1-ay1)*(Y1-ay1));
l2 := Sqrt((X1-ax2)*(X1-ax2)+(Y1-ay2)*(Y1-ay2));
if l1<l2 then l := l1 else l := l2;

It is easy - right ? ;)

ok now we can prepare the final proc for getting the l

if ax1>ax2 then { exchange points - easy and I don't write this }
a1 := (by1-ay1)/(bx1-ax1);
b1 := ay1 - ax1*(by1-ay1)/(bx1-ax1);
X0 := (X1-b1+Y1*a1)/(2*a1);
Y0 := (X1-b1+Y1*a1)/2 + b1;
if (X0>ax1) and (X0<ax2) then
  begin
    l:= Sqrt((X1-X0)*(X1-X0)+(Y1-Y0)*(Y1-Y0));
  end
else
  begin
    l1 := Sqrt((X1-ax1)*(X1-ax1)+(Y1-ay1)*(Y1-ay1));
    l2 := Sqrt((X1-ax2)*(X1-ax2)+(Y1-ay2)*(Y1-ay2));
    if l1<l2 then l := l1 else l := l2;
  end;

this is all, however you must trap examples when the a := 0 ! because in this examples you can get devide by 0 error !

Regards
mirek.
0
 
LVL 10

Expert Comment

by:viktornet
ID: 1338671
Here is something I just wrote, but you try it since I haven't tried it on Delphi.////

function GetClosestRect ( x1, y1, x2, y2, Pt : TPoint ) : boolean;
begin
  Result := ( Pt.x > x1 ) and ( Pt.y > y1 ) and ( Pt.x < x2 ) and ( Pt.y < y2 );  
end;

Example Call:
var
  MyRect : TRect;
begin
  if GetClosestRect( 1, 14, 23, 99, 15 ) then//15 is the point you want to check is closest..
    MyRect := Rect(1, 14, 23, 99);
end;

You can create same procedure but using a TRect type instead of x1,y1,x2,y2......

Hope this helps....

Regards,
Viktor Ivanov
0
 
LVL 10

Expert Comment

by:viktornet
ID: 1338672
A very easy way is to do what you want is to use the function PtInRect()

if PtInRect(Rect, Point) then
  MyRect := Rect;

Regards,
Viktor Ivanov

0
 
LVL 3

Expert Comment

by:mirek071497
ID: 1338673
Yes -victornet, but what when the point is outside rect ? ;)
0
 
LVL 10

Expert Comment

by:viktornet
ID: 1338674
Not exactly sure,....maybe your solution is better..but here is something he might try......this is only for the width,,,,you do it for both width and height...

var
  Rect, MyRect : TRect;
  pt : TPoint;
  i : Integer;
begin
  GetCursorPos(pt);
  for i := 0 to (Width div Rect.Right) do
  begin
    Rect :=Rect (i*Rect.Right, 0, (i*Rect.Right)+Rect.Right, 100);
    if PtInRect(Rect, pt) then
      MyRect := Rect;
  end;
end;

0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 3

Expert Comment

by:mirek071497
ID: 1338675
so you say that the brainware need to try with many rect to see if the other point is in the rect ?!!!!
0
 
LVL 10

Expert Comment

by:viktornet
ID: 1338676
Not exactly...What I say is that you way is an original way to do that, and he is suppose to use yours, but he can try mine as well if he wants to... Just trying to give other pointers....he might learn something new from other example ;-)

Regards,
Viktor Ivanov
0
 
LVL 2

Author Comment

by:brainware
ID: 1338677
Not what i was looking for..
But i got help from SPACEBRAIN that was so nice to drop by my home.
Whatever i think you 100% mis-understod question..

I wanted to check what value that was closest, but found a new way insted..

0
 
LVL 3

Expert Comment

by:mirek071497
ID: 1338678

so what you was asking for ? I can't understand :( and why you accept my answe ?
0
 
LVL 2

Author Comment

by:brainware
ID: 1338679
I acepted it, so if u where some points wanting #"/)" as mabye not..
i would not get my head pulled off...

But ill save the code and try it out, it looks like somthing that was worth this anyway..

So Thanks anyway.. .) I think i can use it for other purpose.

Mvh.
Michael V. Andersen
0
 
LVL 2

Author Comment

by:brainware
ID: 1338680
Old Question but anyway.. what i tryed to do was get Block that was Clicked on in game-map, i was properly tired :))

whatever you algo is nice tho.. understand it and already know where i can use it :))
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Delphi with SQL Natvie Client 15 86
PDF library for Delphi 2 107
Delphi component that can load a DLL in design time? 8 53
Magic Software info 18 125
This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Hi friends,  in this video  I'll show you how new windows 10 user can learn the using of windows 10. Thank you.
Learn how to create flexible layouts using relative units in CSS.  New relative units added in CSS3 include vw(viewports width), vh(viewports height), vmin(minimum of viewports height and width), and vmax (maximum of viewports height and width).

863 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now