     angle = floor(angle / czm_piOverFour + 0.5) * czm_piOverFour;
 #endif
 
-    vec4 clippedPositionEC;
-    clipLineSegmentToNearPlane(prevEC.xyz, positionEC.xyz, p0, clipped, culledByNearPlane, clippedPositionEC);
-    clipLineSegmentToNearPlane(nextEC.xyz, positionEC.xyz, p1, clipped, culledByNearPlane, clippedPositionEC);
-    clipLineSegmentToNearPlane(positionEC.xyz, usePrevious ? prevEC.xyz : nextEC.xyz, endPointWC, clipped, culledByNearPlane, clippedPositionEC);
+    vec4 clippedPrevWC, clippedPrevEC;
+    bool prevSegmentClipped, prevSegmentCulled;
+    clipLineSegmentToNearPlane(prevEC.xyz, positionEC.xyz, clippedPrevWC, prevSegmentClipped, prevSegmentCulled, clippedPrevEC);
+
+    vec4 clippedNextWC, clippedNextEC;
+    bool nextSegmentClipped, nextSegmentCulled;
+    clipLineSegmentToNearPlane(nextEC.xyz, positionEC.xyz, clippedNextWC, nextSegmentClipped, nextSegmentCulled, clippedNextEC);
+
+    bool segmentClipped, segmentCulled;
+    vec4 clippedPositionWC, clippedPositionEC;
+    clipLineSegmentToNearPlane(positionEC.xyz, usePrevious ? prevEC.xyz : nextEC.xyz, clippedPositionWC, segmentClipped, segmentCulled, clippedPositionEC);
 
 #ifdef LOG_DEPTH
     czm_vertexLogDepth(czm_projection * clippedPositionEC);
 #endif
 
-    if (culledByNearPlane)
+    if (segmentCulled)
     {
         return vec4(0.0, 0.0, 0.0, 1.0);
     }
 
-    vec2 prevWC = normalize(p0.xy - endPointWC.xy);
-    vec2 nextWC = normalize(p1.xy - endPointWC.xy);
+    if (czm_equalsEpsilon(clippedPositionWC.xy, usePrevious ? clippedPrevWC.xy : clippedNextWC.xy, czm_epsilon1))
+    {
+        // The ends of this segment occupy the same screen space,
+        // so cull it rather than risking an unstable expansion.
+        return vec4(0.0, 0.0, 0.0, 1.0);
+    }
 
-    float expandWidth = width * 0.5;
-    vec2 direction;
+    vec2 directionToPrevWC = normalize(clippedPrevWC.xy - clippedPositionWC.xy);
+    vec2 directionToNextWC = normalize(clippedNextWC.xy - clippedPositionWC.xy);
 
-#ifdef CLIP_POLYLINE
-    if (clipped)
+    // If a segment was culled, we can't use the corresponding direction
+    // computed above. We should never see both of these be true without
+    // `segmentCulled` above also being true.
+    if (prevSegmentCulled)
     {
-        if (prevEC.z - positionEC.z < 0.0)
-        {
-            direction = vec2(prevWC.y, -prevWC.x);
-        }
-        else
-        {
-            direction = vec2(-prevWC.y, prevWC.x);
-        }
+        directionToPrevWC = -directionToNextWC;
     }
-    else
-#endif
-    if (czm_equalsEpsilon(prevEC.xyz - positionEC.xyz, vec3(0.0), czm_epsilon1) || czm_equalsEpsilon(prevWC, -nextWC, czm_epsilon1))
+    else if (nextSegmentCulled)
     {
-        direction = vec2(-nextWC.y, nextWC.x);
+        directionToNextWC = -directionToPrevWC;
     }
-    else if (czm_equalsEpsilon(nextEC.xyz - positionEC.xyz, vec3(0.0), czm_epsilon1))
+
+    vec2 thisSegmentForwardWC, otherSegmentForwardWC;
+    if (usePrevious)
     {
-        direction = vec2(prevWC.y, -prevWC.x);
+        thisSegmentForwardWC = -directionToPrevWC;
+        otherSegmentForwardWC = directionToNextWC;
     }
     else
     {
-        vec2 normal = vec2(-nextWC.y, nextWC.x);
-        direction = normalize((nextWC + prevWC) * 0.5);
-        if (dot(direction, normal) < 0.0)
-        {
-            direction = -direction;
-        }
-
-        // The sine of the angle between the two vectors is given by the formula
-        //         |a x b| = |a||b|sin(theta)
-        // which is
-        //     float sinAngle = length(cross(vec3(direction, 0.0), vec3(nextWC, 0.0)));
-        // Because the z components of both vectors are zero, the x and y coordinate will be zero.
-        // Therefore, the sine of the angle is just the z component of the cross product.
-        float sinAngle = abs(direction.x * nextWC.y - direction.y * nextWC.x);
-        expandWidth = clamp(expandWidth / sinAngle, 0.0, width * 2.0);
+        thisSegmentForwardWC = directionToNextWC;
+        otherSegmentForwardWC =  -directionToPrevWC;
     }
 
-    vec2 offset = direction * expandDirection * expandWidth * czm_pixelRatio;
-    return vec4(endPointWC.xy + offset, -endPointWC.z, 1.0) * (czm_projection * clippedPositionEC).w;
+    vec2 thisSegmentLeftWC = vec2(-thisSegmentForwardWC.y, thisSegmentForwardWC.x);
+    vec2 otherSegmentLeftWC = vec2(-otherSegmentForwardWC.y, otherSegmentForwardWC.x);
+
+    vec2 leftWC = normalize((thisSegmentLeftWC + otherSegmentLeftWC) * 0.5);
+
+    float expandWidth = width * 0.5;
+
+    // The sine of the angle between the two vectors is given by the formula
+    //         |a x b| = |a||b|sin(theta)
+    // which is
+    //     float sinAngle = length(cross(vec3(leftWC, 0.0), vec3(-thisSegmentForwardWC, 0.0)));
+    // Because the z components of both vectors are zero, the x and y coordinate will be zero.
+    // Therefore, the sine of the angle is just the z component of the cross product.
+    vec2 u = -thisSegmentForwardWC;
+    vec2 v = leftWC;
+    float sinAngle = abs(u.x * v.y - u.y * v.x);
+    expandWidth = clamp(expandWidth / sinAngle, 0.0, width * 2.0);
+
+    vec2 offset = leftWC * expandDirection * expandWidth * czm_pixelRatio;
+    return vec4(clippedPositionWC.xy + offset, -clippedPositionWC.z, 1.0) * (czm_projection * clippedPositionEC).w;
 }
 
 vec4 getPolylineWindowCoordinates(vec4 position, vec4 previous, vec4 next, float expandDirection, float width, bool usePrevious, out float angle)


vec4 getPolylineWindowCoordinatesEC(vec4 positionEC, vec4 prevEC, vec4 nextEC, float expandDirection, float width, bool usePrevious, out float angle)
{
    vec4 endPointWC, p0, p1;
    bool culledByNearPlane, clipped;

#ifdef POLYLINE_DASH
    // Compute the window coordinates of the points.

    culledByNearPlane = false;
    clipped = false;

    vec3 p0ToP1 = p1 - p0;
    float magnitude = length(p0ToP1);
    vec3 direction = normalize(p0ToP1);

    // Distance that p0 is behind the near plane. Negative means p0 is
    // in front of the near plane.
    float endPoint0Distance =  czm_currentFrustum.x + p0.z;

    // Camera looks down -Z.
    // When moving a point along +Z: LESS VISIBLE
    //   * Points in front of the camera move closer to the camera.
    //   * Points behind the camrea move farther away from the camera.
    // When moving a point along -Z: MORE VISIBLE
    //   * Points in front of the camera move farther away from the camera.
    //   * Points behind the camera move closer to the camera.

    // Positive denominator: -Z, becoming more visible
    // Negative denominator: +Z, becoming less visible
    // Nearly zero: parallel to near plane
    float denominator = -direction.z;

    if (endPoint0Distance > 0.0 && abs(denominator) < czm_epsilon7)
    {
        // p0 is behind the near plane and the line to p1 is nearly parallel to
        // the near plane, so cull the segment completely.
        culledByNearPlane = true;
    }
    else if (endPoint0Distance > 0.0)
    {
        // p0 is behind the near plane, and the line to p1 is moving distinctly
        // toward or away from it.

        // t = (-plane distance - dot(plane normal, ray origin)) / dot(plane normal, ray direction)
        float t = endPoint0Distance / denominator;
        if (t < 0.0 || t > magnitude)
        {
            // Near plane intersection is not between the two points.
            // We already confirmed p0 is behind the naer plane, so now
            // we know the entire segment is behind it.
            culledByNearPlane = true;
        }
        else
        {
            // Segment crosses the near plane, update p0 to lie exactly on it.
            p0 = p0 + t * direction;

            // Numerical noise might put us a bit on the wrong side of the near plane.
            // Don't let that happen.
            p0.z = min(p0.z, -czm_currentFrustum.x);

            clipped = true;
        }
    }
