[MI-L] ATAN2

2006-04-29 Thread Spencer Simpson
A recent private message form Jacques Paris suggested I should explain the
atan2 function and why it is needed.

You may already know that MapBasic contains an atn() function to calculate
the inverse of the tangent function. 
Atn is often used in spatial applications to calculate a "direction".  But
"direction" means different things in different circumstances, an
circumstances often dictate that the "direction" we interpret from atn() is
not 
the "direction" we want.  

If we're talking about the "direction" of a line segment, and if we don't
care which end of the segment is "first", then "direction" simply means the
segment's orientation in space; and something calculated from atn may be
sufficient.

But what if we want the "direction" of travel down a road?  If we use return
values from "atn", we cannot tell southwest (tan(-3*pi/4)=1) from northeast
(tan(pi/4)=1).  atn(1) returns pi/4 and we have to interpret it as "either
southwest OR northeast".  We can't tell which.

Why is this the case? Well, in order for a relation between numbers to be
considered a "function" (in the mathematical sense) there has to be a single
value in the codomain for each value in the domain (the codomain of a
function is called its "range").

Let's consider atn(0). If we set x=atn(0), this means tan (x) = 0.  But tan
(j*2*pi)=0 for every integer j. An implementation of atn() has to choose
exactly one of the infinite possible values to be considered a "function".
All inverse trigonometric functions have this problem, and mathematicians
get around it by choosing a range of values to return. Since

Lim(a->pi/2, tan(a)) = infinity
Lim(-pi/2<-a, atn(a)) = -infinity

we can choose 

Lim(a->infinity, atn(a)) = pi/2
Lim(a->-infinity, atn(a)) = -pi/2

And so the traditional range of atn is -pi/2 <= atn(a) <= pi/2. This is also
the range MapBasic uses. 

If you don't need to tell the difference between southwest and northeast
(called "sense"), this is sufficient. 

But if you do, atn() won't work.  Now we do care which end of the segment is
first; we're imparting a sense to the line segment, interpreting it as a
vector.  "Direction" now means the combination of the vector's orientation
and sense.  In order to have a function that returns all direction values
(which range from -pi to pi), you need more information than just one
number: You must consider the signs of both components of the vector.  Thus,
a "two argument atn" is required.

The name "atan2" harks back to the days of numerical processing in FORTRAN.
The people who built the function into FORTRAN probably called it ATAN2 to
mean "two argument ATN".  But perhaps "azimuth" would be a better name.

So here is my implementation of atan2 in MapBasic, built off the atn
function. This also appeared in an earlier message.

function atan2 (ByVal dx as float, 
ByVal dy as float) as float

dim a as float

'use atn, avoiding division by zero. -pi/4 <= a <= pi/4
If (abs (dx) > abs (dy)) 
   then a = atn (dy/dx)
   else a = atn (dx/dy)
if a < 0
   then a = -PI/2-a  ' a is negative, so we're adding
   else a = PI/2-a
end if
End if
if dx < 0
   then if dy < 0
   then a = a - PI
   else a = a + PI
end if
atan2 = a
end if
end function


Hope this helps
Spencer

___
MapInfo-L mailing list
MapInfo-L@lists.directionsmag.com
http://www.directionsmag.com/mailman/listinfo/mapinfo-l


RE: [MI-L] Updating column with number of objects nearest apolyline...

2006-04-29 Thread Peter Horsbøll Møller
Paul,

I would recommend that you use the Distance Calculator tool. With this tool you 
can find the nearest object in one table to each object in another table.
You would need MapInfo 8.0 to be able to do this though.

If you don't have MapInfo 8.0, I have nmade a tool called NearestObject that 
can be found on Directionsmag.com under Tools.

Both tools will give you a result table containing an id from both table and a 
line showing the "distance". The Distance Calculator also updates a column with 
the distance.

HTH,

Peter Horsbøll Møller
GIS Developer, MTM
Geographical Information & IT
 
COWI A/S
Odensevej 95
DK-5260 Odense S.
Denmark
 
Tel +45 6311 4900
Direct  +45 6311 4908
Mob +45 5156 1045
Fax +45 6311 4949
E-mail  [EMAIL PROTECTED]
http://www.cowi.dk/gis

-Original Message-
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Spencer Simpson
Sent: Friday, April 28, 2006 2:51 PM
To: [EMAIL PROTECTED]; 'Paul Donnelly'
Cc: mapinfo-l@lists.directionsmag.com
Subject: RE: [MI-L] Updating column with number of objects nearest apolyline...

Line-based Voronoi polygons would be nice, wouldn't they?  

There's a way to approximate them by generating intermediate points but I'm not 
sure the cure isn't worse than the disease...

Spencer



From: [EMAIL PROTECTED]
[mailto:[EMAIL PROTECTED] On Behalf Of Lars I.
Nielsen (GisPro)
Sent: Thursday, April 27, 2006 4:48 PM
To: Paul Donnelly
Cc: mapinfo-l@lists.directionsmag.com
Subject: Re: [MI-L] Updating column with number of objects nearest apolyline...


Hi Poul,

Would a feasible way not be to "explode" your polylines to node point objects, 
and generate voronoi polygons around these points ? Preserving some sort of 
"polyline ID" for each polygon.

That way you could find the points closest to any node, and sum the counts 
using the "polyline ID" as aggregator.

Unless your polyline are really weird, it ought to give you a reasonable 
result, or at least one that only counts single incident points once.


Best regards / Med venlig hilsen
Lars I. Nielsen
GisPro



Paul Donnelly wrote: 

Hello all! 

Was wondering if anyone can help me out with a little problem I need 
help in solving? Basically, I have two MapInfo tables - One table containing 
polylines representing road networks, and a second table containing point 
objects representing the locations of road accidents.

I need a method of calculating the sum of accidents per road link.
Previously I had buffered the polylines and then simply used the 'update 
column' function to sum up the number of objects within the buffer. The problem 
with this though was that where two polylines meet at a junction there was an 
overlap with the buffers and so when an accident point falls in this overlap it 
is double counted within both overlapping buffers. With small sections of road 
networks I simply edited the buffers to remove the overlap and then used the 
update column method. The problem now is that I have a lot of road newtork data 
and if I were to go round and remove each overlap for each individual section 
I'd still be here this time next year! 

So, ideally I need a method of assigning accident points to a single 
road link which is nearest. Then I need to update a column within the link 
table to count the number of accidents assigned to each particular road 
section. Any help solving this problem would much appreciated! 

Thanks in advance, 

Paul Donnelly 

Email: [EMAIL PROTECTED]  





**
This message contains information which is confidential and may also be 
privileged. It is for the exclusive use of the intended recipient(s). If you 
are not the intended recipient(s) please note that any form of distribution, 
copying or use of this communication or the information in it is strictly 
prohibited and may be unlawful. If you have received this communication in 
error please return it to the sender and then delete the email and destroy any 
copies of it. Thank you.

Hyder cannot guarantee that this message or any attachment is 
virus-free or has not been intercepted or changed. 

Any opinions or other information in this message that do not relate to 
the official business of the Company are neither given nor endorsed
by it.

**




___
MapInfo-L mailing list
MapInfo-L@lists.directionsmag.com
http://www.directionsmag.com/mailman/listinfo/mapinfo-l
  



___
MapInfo-L mailing list
MapInfo-L@lists.directionsmag.com
http://www.directionsmag.com/mailman/listinfo/ma