Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Get closest value?

Posted on 1998-09-05
12
Medium Priority
?
306 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
Technology Partners: 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!

 
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

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

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…
Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Visualize your data even better in Access queries. Given a date and a value, this lesson shows how to compare that value with the previous value, calculate the difference, and display a circle if the value is the same, an up triangle if it increased…
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…
Suggested Courses

618 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