(I attempted to file a bug ticket at first, however Trac is spitting
out Python errors.. Trying to post to this list wasn't the easiest,
either, with Mailman not understanding RFC5233 +tagging..)
The foremost issue I found in the code of the buggy 'Align Nodes'
feature was the multiplications overflowing the 32-bit integer
datatype in Coord::length (src/Maps/Coord.h, line 83 as of 20090818
checkout). This bug was causing src/Maps/Coord.cpp:angle() to return a
bogus value.
Problem code in length():
return sqrt((double)Lat*Lat+Lon*Lon));
A fix by someone from a time when you had to be paranoid about C
compiler behavour:
return sqrt((double)((long)Lat*(long)Lat+(long)Lon*(long)Lon));
In the process of locating the above bug, I made a few code rewrites
'for clarity', that I should probably include below, just in case I've
forgotten a subtlety.
src/Maps/Coord.cpp:
double angle(Coord p1)
{
if (p1.length() == 0)
return 0;
double adjacent = (double)p1.lon() / p1.length();
if (p1.lat() > 0)
return acos(adjacent);
return -acos(adjacent);
}
The original code mucked-about with constant coordinate conversions
(intToRad), which is unnecessary as (Trigonometric) ratios were
involved.
src/Maps/FeatureManipulations.cpp:alignNodes():
void alignNodes(MapDocument* theDocument, CommandList* theList,
PropertiesDock* theDock)
{
[..]
//we do the alignment
Coord pos(0,0);
const Coord p1(Nodes[0]->position());
const Coord p2(Nodes[1]->position()-p1);
const double slope = angle(p2);
for (int i=2; i<Nodes.size(); ++i) {
pos=Nodes[i]->position()-p1;
rotate(pos,-slope);
pos.setLat(0);
rotate(pos,slope);
pos=pos+p1;
theList->add(new MoveTrackPointCommand( Nodes[i], pos,
theDocument->getDirtyOrOriginLayer(Nodes[i]->layer()) ));
}
}
(I had an "Aha!" moment when I figured out how this code worked. Nice idea. :)
--
Chris Baird,, <[email protected]>
_______________________________________________
Merkaartor mailing list
[email protected]
http://lists.openstreetmap.org/listinfo/merkaartor