/// <summary> /// Calculate the clip location /// </summary> /// <param name="hitSegment">the hitting segment</param> /// <param name="beginNode">begin node</param> /// <param name="spineVector"></param> /// <param name="pressureDelta"></param> /// <returns>the clip location. not-clip if return StrokeFIndices.BeforeFirst</returns> private double CalculateClipLocation( ContourSegment hitSegment, StrokeNodeData beginNode, Vector spineVector, double pressureDelta) { double findex = StrokeFIndices.BeforeFirst; bool clipIt = hitSegment.IsArc ? true //? (WhereIsVectorAboutArc(beginNode.Position - hitSegment.Begin - hitSegment.Radius, // -hitSegment.Radius, hitSegment.Vector - hitSegment.Radius) == HitResult.Hit) : (WhereIsVectorAboutVector( beginNode.Position - hitSegment.Begin, hitSegment.Vector) == HitResult.Left); if (clipIt) { findex = hitSegment.IsArc ? ClipTestArc(spineVector, pressureDelta, (hitSegment.Begin + hitSegment.Radius - beginNode.Position) / beginNode.PressureFactor, hitSegment.Radius / beginNode.PressureFactor) : ClipTest(spineVector, pressureDelta, (hitSegment.Begin - beginNode.Position) / beginNode.PressureFactor, (hitSegment.End - beginNode.Position) / beginNode.PressureFactor); // NTRAID#WINDOWS-1384646-2005/11/17-WAYNEZEN, // ClipTest returns StrokeFIndices.AfterLast to indicate a false hit test. // But the caller CutTest expects StrokeFIndices.BeforeFirst when there is no hit. if ( findex == StrokeFIndices.AfterLast ) { findex = StrokeFIndices.BeforeFirst; } else { System.Diagnostics.Debug.Assert(findex >= 0 && findex <= 1); } } return findex; }
/// <summary> /// Helper function to Hit-test against the two stroke nodes only (excluding the connecting quad). /// </summary> /// <param name="hitSegment"></param> /// <param name="beginNode"></param> /// <param name="endNode"></param> /// <param name="result"></param> /// <returns></returns> private bool HitTestStrokeNodes( ContourSegment hitSegment, StrokeNodeData beginNode, StrokeNodeData endNode, ref StrokeFIndices result) { // First, find out if hitSegment intersects with either of the ink nodes bool isHit = false; for (int node = 0; node < 2; node++) { Point position; double pressureFactor; if (node == 0) { if (isHit && DoubleUtil.AreClose(result.BeginFIndex, StrokeFIndices.BeforeFirst)) { continue; } position = beginNode.Position; pressureFactor = beginNode.PressureFactor; } else { if (isHit && DoubleUtil.AreClose(result.EndFIndex, StrokeFIndices.AfterLast)) { continue; } position = endNode.Position; pressureFactor = endNode.PressureFactor; } Vector hitBegin, hitEnd; // Adjust the segment for the node's pressure factor if (hitSegment.IsArc) { hitBegin = hitSegment.Begin - position + hitSegment.Radius; hitEnd = hitSegment.Radius; } else { hitBegin = hitSegment.Begin - position; hitEnd = hitBegin + hitSegment.Vector; } if (pressureFactor != 1) { System.Diagnostics.Debug.Assert(DoubleUtil.IsZero(pressureFactor) == false); hitBegin /= pressureFactor; hitEnd /= pressureFactor; } // Hit-test the node against the segment if (hitSegment.IsArc ? HitTestPolygonCircle(_vertices, hitBegin, hitEnd) : HitTestPolygonSegment(_vertices, hitBegin, hitEnd)) { isHit = true; if (node == 0) { result.BeginFIndex = StrokeFIndices.BeforeFirst; if (DoubleUtil.AreClose(result.EndFIndex, StrokeFIndices.AfterLast)) { break; } } else { result.EndFIndex = StrokeFIndices.AfterLast; if (beginNode.IsEmpty) { result.BeginFIndex = StrokeFIndices.BeforeFirst; break; } if (DoubleUtil.AreClose(result.BeginFIndex, StrokeFIndices.BeforeFirst)) { break; } } } } return isHit; }