?
Solved

Get closest value?

Posted on 1998-09-05
12
Medium Priority
?
305 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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 60 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
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
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
 
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

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Sometimes it takes a new vantage point, apart from our everyday security practices, to truly see our Active Directory (AD) vulnerabilities. We get used to implementing the same techniques and checking the same areas for a breach. This pattern can re…
In this video, Percona Solutions Engineer Barrett Chambers discusses some of the basic syntax differences between MySQL and MongoDB. To learn more check out our webinar on MongoDB administration for MySQL DBA: https://www.percona.com/resources/we…
Suggested Courses

765 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