ICurve.QueryTangent having problems with DistanceAlongCurve = 0.0

1173
5
10-27-2011 03:42 AM
AndryJoos
Occasional Contributor
We have encountered a strange behaviour using ICurve.QueryTangent (on straight lines, not tested with other types). If you supply a value of exactly 0.0 (zero) for the DistanceAlongCurve argument, the resulting tangent is/has an empty geometry. Changing the value to something very close to 0.0 (zero), for example 5.0e-324, QueryTangent works as expected. The wrong behaviour doesn't seem to be dependant on the other values supplied to QueryTangent (extension method, length of the resulting tangent etc.)

This is our workaround which corrects the problem for us, however it's kind of an unpleasent hack. Can someone else confirm this behaviour? Could you coders at Esri look at this too, to see if the QueryTangent method can not handle zero values correctly (and if so, update the documentation accordingly or correct the problem)?

Thank you!
Tags (2)
0 Kudos
5 Replies
NeilClemmons
Regular Contributor III
I'm not having any problems creating the tangent line.  You may want to post your code to see if someone sees something wrong.
0 Kudos
AndryJoos
Occasional Contributor
Neil, thank you for reacting. While we haven't tried to reproduce this with a simple example or isolated code, here's the relevant part of the code. It's (legacy) Delphi code, running in ArcMap 10.0 SP3.

[...]
var
  pPointOnLine: IPoint;
  rDistOnLine: Double;
  rDummy: Double;
  bDummy: WordBool;
  pTangent1: ILine;
  [...]
begin
  pTangent1 := CoLine.Create as ILine;
  pPointOnLine := CoPoint.Create as IPoint;
  pCurve.QueryPointAndDistance(esriExtendTangents, pPoint, False, pPointOnLine, rDistOnLine, rDummy, bDummy);
  pCurve.QueryTangent(esriExtendTangents, rDistOnLine, False, 1.0, pTangent1);
  [...]


At this point, pTangent1 has an empty geometry if rDistOnLine was exactly 0.0 before calling QueryTangent. pCurve is defined as ICurve, and given into the method, and so is pPoint, which is an IPoint having valid coordinates (so no var declaration for these). pCurve is actually a geometry coming straight from the database, pPoint is a click/snap-coordinate.

Adding the following code right before QueryTangent makes the whole method working every single time:

  if (0.0 = rDistOnLine) then
    rDistOnLine := Math.MinDouble;


The parts of code not supplied consist of handling errors, I skipped it from the example.
0 Kudos
NeilClemmons
Regular Contributor III
You are calling QueryPointAndDistance prior to calling QueryTangent.  rDistOnLine is being passed into that call.  QueryPointAndDistance updates that parameter (it's passed by reference) to the distance along the line of the point you pass in.  If the point you pass into QueryPointAndDistance does not match the FromPoint of the curve (x, y coords must match exactly - all the way out to however many decimal places it has) then rDistOnLine will no longer have a value of 0 when the call returns.
0 Kudos
AndryJoos
Occasional Contributor
Neil, thanks for the reply! It's great to discuss.

What you describe is of course the intended behaviour of the function. Let me explain: QueryPointAndDistance is used to find the distance of pPoint on pCurve. We want to find get the tangent of pCurve at that point. There are cases where pPoint exactly matches the from point, resulting in rDistOnLine being exactly zero (0.0). In that case, QueryTangent fails, unless I change rDistOnLine from exactly zero to 5.0e-324 (which is almost, but not quite exactly zero). Resulting in the very same tangent as I would expect it from calling QueryTangent with 0.0 (exactly zero). However, when calling QueryTangent with DistOnCurve = 0.0, the resulting geometry is empty, which it is not when calling with DistOnCurve = 5.0e-324.

Ok, I'm having a hard time to explain what the method does. Hope I have been able to clarify things a bit? Actually, it doesn't matter which method changes or sets rDistOnLine. Whenever it is exactly zero, QueryTangent generates an emtpy geometry.
0 Kudos
NeilClemmons
Regular Contributor III
Have you tried a simplified test?  I've tested it in several scenarios with a value of 0 and have not run into any problems.
0 Kudos