-
Notifications
You must be signed in to change notification settings - Fork 3.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Polyline Gaps #2265
Polyline Gaps #2265
Conversation
Code looks good (I didn't run it though). Does this warrant a mention in CHANGES.md? |
@pjcozzi |
@shunter since you have the complete CZML polyline that originally detected this problem, can you merge this after verifying everything works? |
Still getting gaps. Sandcastle: var viewer = new Cesium.Viewer('cesiumContainer');
var scene = viewer.scene;
var czml =
[
{
"id":"document",
"version":"1.0"
},
{
"id":"route",
"polyline":{
"followSurface":false,
"width":1,
"material":{
"solidColor":{
"color":{
"rgba":[
255,0,0,255
]
}
}
},
"positions":{
"cartesian":[
-3591987.63453649,5161973.3486444,1190251.05756476,
-3628083.55387411,5165232.94262105,1060369.2289924,
-3663885.23771364,5166176.8496425,924863.604149131,
-3699175.1634344,5164520.94347153,783745.252709972,
-3699175.1634336,5164520.94347154,783745.252713645,
-3699502.86098311,5164543.69243247,782058.090405673,
-3699671.57770435,5164682.19775128,780354.861274571,
-3699679.5349048,5164934.3585661,778657.738656253,
-3699527.00703476,5165296.63612803,776988.727947579,
-3699216.30934082,5165764.10253274,775369.403766365,
-3698751.76552228,5166330.50307426,773820.651264288,
-3698139.65485485,5166988.33245244,772362.412582204
]
}
}
}
];
var czmlDataSource = new Cesium.CzmlDataSource();
czmlDataSource.load(czml, 'Built-in CZML');
viewer.dataSources.add(czmlDataSource);
scene.camera.viewRectangle(Cesium.Rectangle.fromDegrees(121, 5, 129, 11)); |
@shunter I updated the epsilon value. The CZML file you sent me now works. Though any line segment less than a millimeter in length will fail to draw. |
@shunter did you want to retest or we can merge? |
Seems like the epsilon value is still not high enough to handle all cases. I changed the positions from my last sandcastle example and can still produce gaps:
(the two closest points have a distance of about 0.037 meters) In my testing, this seems to be approximately the farthest apart where the segment disappears. Given the Earth's radius, that seems to more or less line up with the limitation being a result of the values being stored in single precision. |
I guess I should point out that the error will vary depending on the magnitude of the components, which means that |
If the goal is to remove duplicates, shouldn't epsilon15 (possibly 16) be used since that is the resolution of double precision, 64-bit floating point numbers? |
Well, the values end up as 32-bit floats in the shader, so that's the precision that we work with. I sent Dan a link to this post which goes into the details of why the absolute epsilon approach does not work for detecting precision problems, and what to do instead: http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ |
Also check out http://realtimecollisiondetection.net/blog/?p=89 |
@shunter I added functions for testing relative tolerance. If these look OK to you, I'll take a look at all of the existing |
return (left === right) || | ||
((defined(left)) && | ||
(defined(right)) && | ||
(((Math.abs(left.x - right.x) <= absoluteEpsilon) && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this logic right? Shouldn't it allow left.x
to be near right.x
in absolute tolerance, and allow left.y
to be near right.y
in relative tolerance?
Basically,
((Math.abs(left.x - right.x) <= absoluteEpsilon) ||
(Math.abs(left.x - right.x) <= relativeEpsilon * Math.max(Math.abs(left.x), Math.abs(right.x)))) &&
((Math.abs(left.y - right.y) <= absoluteEpsilon) ||
(Math.abs(left.y - right.y) <= relativeEpsilon * Math.max(Math.abs(left.y), Math.abs(right.y))))
Or alternatively this can be simplified using the logic from http://realtimecollisiondetection.net/blog/?p=89
(Math.abs(left.x - right.x) <= Math.max(absoluteEpsilon, relativeEpsilon * Math.max(Math.abs(left.x), Math.abs(right.x)))) &&
(Math.abs(left.y - right.y) <= Math.max(absoluteEpsilon, relativeEpsilon * Math.max(Math.abs(left.y), Math.abs(right.y))))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, you can just use the function in CesiumMath
.
CesiumMath.equalsEpsilonRelativeAndAbsolute(left.x, right.x, absoluteEpsilon, relativeEpsilon) &&
CesiumMath.equalsEpsilonRelativeAndAbsolute(left.y, right.y, absoluteEpsilon, relativeEpsilon)
@shunter This is ready for another look. |
Do we want this for 1.4? |
I moved the changes to 1.5 and merged in master. @shunter do you have time to take a final look at this? If not, I can do it. |
Conflicts: CHANGES.md
@shunter I made the changes that we discussed offline. This is ready for another review. |
(Math.abs(left.y - right.y) <= epsilon)); | ||
(defined(left) && | ||
defined(right) && | ||
Math.abs(left.x - right.x) <= Math.max(absoluteEpsilon, relativeEpsilon * Math.max(Math.abs(left.x), Math.abs(right.x))) && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These functions can just call CesiumMath.equalsEpsilon(left.x, right.x, relativeEpsilon, absoluteEpsilon)
can't they? Then you can drop the defaultValue
above. Same throughout.
@shunter This is ready for another look. Implementing |
expect(CesiumMath.equalsEpsilon(1.0, 1.0, 0.0)).toEqual(true); | ||
expect(CesiumMath.equalsEpsilon(1.0, 1.0, 1.0)).toEqual(true); | ||
expect(CesiumMath.equalsEpsilon(1.0, 1.0 + CesiumMath.EPSILON7, CesiumMath.EPSILON7)).toEqual(true); | ||
expect(CesiumMath.equalsEpsilon(1.0, 1.0 + CesiumMath.EPAILON7, CesiumMath.EPSILON9)).toEqual(false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo here: EPAILON7
. I'll fix and merge.
For #2136.
CC @shunter @mramato