Solved

Get closest value?

Posted on 1998-09-05
12
294 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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
Yes -victornet, but what when the point is outside rect ? ;)
0
 
LVL 10

Expert Comment

by:viktornet
Comment Utility
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
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 
LVL 3

Expert Comment

by:mirek071497
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility

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

Author Comment

by:brainware
Comment Utility
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
Comment Utility
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

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

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…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

762 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

11 Experts available now in Live!

Get 1:1 Help Now