protected bool IsInvalidCutTestResult(StrokeFIndices result) { if (DoubleUtil.AreClose(result.BeginFIndex, result.EndFIndex) || (DoubleUtil.AreClose(result.BeginFIndex, StrokeFIndices.BeforeFirst) && result.EndFIndex < 0.0) || (result.BeginFIndex > 1.0 && DoubleUtil.AreClose(result.EndFIndex, StrokeFIndices.AfterLast))) { return(true); } return(false); }
internal virtual StrokeFIndices CutTest(StrokeNodeData beginNode, StrokeNodeData endNode, Quad quad, Point hitBeginPoint, Point hitEndPoint) { StrokeFIndices empty = StrokeFIndices.Empty; for (int i = beginNode.IsEmpty ? 1 : 0; i < 2; i++) { Point point = (i == 0) ? beginNode.Position : endNode.Position; double num = (i == 0) ? beginNode.PressureFactor : endNode.PressureFactor; Vector hitBegin = hitBeginPoint - point; Vector hitEnd = hitEndPoint - point; if (num != 1.0) { hitBegin /= num; hitEnd /= num; } if (!HitTestPolygonSegment(_vertices, hitBegin, hitEnd)) { continue; } if (i == 0) { empty.BeginFIndex = StrokeFIndices.BeforeFirst; empty.EndFIndex = 0.0; continue; } empty.EndFIndex = StrokeFIndices.AfterLast; if (beginNode.IsEmpty) { empty.BeginFIndex = StrokeFIndices.BeforeFirst; } else if (empty.BeginFIndex != StrokeFIndices.BeforeFirst) { empty.BeginFIndex = 1.0; } } if (empty.IsFull) { return(empty); } if (empty.IsEmpty && (quad.IsEmpty || !HitTestQuadSegment(quad, hitBeginPoint, hitEndPoint))) { return(empty); } if (empty.BeginFIndex != StrokeFIndices.BeforeFirst) { empty.BeginFIndex = ClipTest((endNode.Position - beginNode.Position) / beginNode.PressureFactor, endNode.PressureFactor / beginNode.PressureFactor - 1f, (hitBeginPoint - beginNode.Position) / beginNode.PressureFactor, (hitEndPoint - beginNode.Position) / beginNode.PressureFactor); } if (empty.EndFIndex != StrokeFIndices.AfterLast) { empty.EndFIndex = 1.0 - ClipTest((beginNode.Position - endNode.Position) / endNode.PressureFactor, beginNode.PressureFactor / endNode.PressureFactor - 1f, (hitBeginPoint - endNode.Position) / endNode.PressureFactor, (hitEndPoint - endNode.Position) / endNode.PressureFactor); } if (IsInvalidCutTestResult(empty)) { return(StrokeFIndices.Empty); } return(empty); }
internal StrokeFIndices CutTest(Point begin, Point end) { if (!IsValid) { return(StrokeFIndices.Empty); } StrokeFIndices fragment = _operations.CutTest(_lastNode, _thisNode, ConnectingQuad, begin, end); return(BindFIndicesForLassoHitTest(fragment)); }
internal override StrokeFIndices CutTest(StrokeNodeData beginNode, StrokeNodeData endNode, Quad quad, Point hitBeginPoint, Point hitEndPoint) { Vector vector = beginNode.IsEmpty ? new Vector(0.0, 0.0) : (beginNode.Position - endNode.Position); Vector vector2 = hitBeginPoint - endNode.Position; Vector vector3 = hitEndPoint - endNode.Position; if (!_nodeShapeToCircle.IsIdentity) { vector = _nodeShapeToCircle.Transform(vector); vector2 = _nodeShapeToCircle.Transform(vector2); vector3 = _nodeShapeToCircle.Transform(vector3); } StrokeFIndices empty = StrokeFIndices.Empty; double num = 0.0; double num2 = _radius * (double)endNode.PressureFactor; if (StrokeNodeOperations.GetNearest(vector2, vector3).LengthSquared <= num2 * num2) { empty.EndFIndex = StrokeFIndices.AfterLast; empty.BeginFIndex = (beginNode.IsEmpty ? StrokeFIndices.BeforeFirst : 1.0); } if (!beginNode.IsEmpty) { num = _radius * (double)beginNode.PressureFactor; if (StrokeNodeOperations.GetNearest(vector2 - vector, vector3 - vector).LengthSquared <= num * num) { empty.BeginFIndex = StrokeFIndices.BeforeFirst; if (!DoubleUtil.AreClose(empty.EndFIndex, StrokeFIndices.AfterLast)) { empty.EndFIndex = 0.0; } } } if (empty.IsFull || quad.IsEmpty || (empty.IsEmpty && !StrokeNodeOperations.HitTestQuadSegment(quad, hitBeginPoint, hitEndPoint))) { return(empty); } if (!DoubleUtil.AreClose(empty.BeginFIndex, StrokeFIndices.BeforeFirst)) { empty.BeginFIndex = ClipTest(-vector, num, num2, vector2 - vector, vector3 - vector); } if (!DoubleUtil.AreClose(empty.EndFIndex, StrokeFIndices.AfterLast)) { empty.EndFIndex = 1.0 - ClipTest(vector, num2, num, vector2, vector3); } if (IsInvalidCutTestResult(empty)) { return(StrokeFIndices.Empty); } return(empty); }
private StrokeFIndices BindFIndices(StrokeFIndices fragment) { if (!fragment.IsEmpty) { if (!DoubleUtil.AreClose(fragment.BeginFIndex, StrokeFIndices.BeforeFirst)) { fragment.BeginFIndex += _index - 1; } if (!DoubleUtil.AreClose(fragment.EndFIndex, StrokeFIndices.AfterLast)) { fragment.EndFIndex += _index - 1; } } return(fragment); }
internal StrokeFIndices CutTest(StrokeNode hitNode) { if (!IsValid || !hitNode.IsValid) { return(StrokeFIndices.Empty); } IEnumerable <ContourSegment> contourSegments = hitNode.GetContourSegments(); StrokeFIndices strokeFIndices = _operations.CutTest(_lastNode, _thisNode, ConnectingQuad, contourSegments); if (_index != 0) { return(BindFIndices(strokeFIndices)); } return(strokeFIndices); }
private StrokeFIndices BindFIndicesForLassoHitTest(StrokeFIndices fragment) { if (!fragment.IsEmpty) { if (DoubleUtil.AreClose(fragment.BeginFIndex, StrokeFIndices.BeforeFirst)) { fragment.BeginFIndex = ((_index == 0) ? StrokeFIndices.BeforeFirst : ((double)(_index - 1))); } else { fragment.BeginFIndex += _index - 1; } if (DoubleUtil.AreClose(fragment.EndFIndex, StrokeFIndices.AfterLast)) { fragment.EndFIndex = (_isLastNode ? StrokeFIndices.AfterLast : ((double)_index)); } else { fragment.EndFIndex += _index - 1; } } return(fragment); }
private bool HitTestStrokeNodes(ContourSegment hitSegment, StrokeNodeData beginNode, StrokeNodeData endNode, ref StrokeFIndices result) { bool flag = false; for (int i = 0; i < 2; i++) { Point position; double num; if (i == 0) { if (flag && DoubleUtil.AreClose(result.BeginFIndex, StrokeFIndices.BeforeFirst)) { continue; } position = beginNode.Position; num = beginNode.PressureFactor; } else { if (flag && DoubleUtil.AreClose(result.EndFIndex, StrokeFIndices.AfterLast)) { continue; } position = endNode.Position; num = endNode.PressureFactor; } Vector vector; Vector vector2; if (hitSegment.IsArc) { vector = hitSegment.Begin - position + hitSegment.Radius; vector2 = hitSegment.Radius; } else { vector = hitSegment.Begin - position; vector2 = vector + hitSegment.Vector; } if (num != 1.0) { vector /= num; vector2 /= num; } if (!(hitSegment.IsArc ? HitTestPolygonCircle(_vertices, vector, vector2) : HitTestPolygonSegment(_vertices, vector, vector2))) { continue; } flag = true; if (i == 0) { result.BeginFIndex = StrokeFIndices.BeforeFirst; if (DoubleUtil.AreClose(result.EndFIndex, StrokeFIndices.AfterLast)) { break; } continue; } result.EndFIndex = StrokeFIndices.AfterLast; if (beginNode.IsEmpty) { result.BeginFIndex = StrokeFIndices.BeforeFirst; break; } if (DoubleUtil.AreClose(result.BeginFIndex, StrokeFIndices.BeforeFirst)) { break; } } return(flag); }
internal virtual StrokeFIndices CutTest(StrokeNodeData beginNode, StrokeNodeData endNode, Quad quad, IEnumerable <ContourSegment> hitContour) { if (beginNode.IsEmpty) { if (HitTest(beginNode, endNode, quad, hitContour)) { return(StrokeFIndices.Full); } return(StrokeFIndices.Empty); } StrokeFIndices result = StrokeFIndices.Empty; bool flag = true; Vector spineVector = (endNode.Position - beginNode.Position) / beginNode.PressureFactor; Vector spineVector2 = (beginNode.Position - endNode.Position) / endNode.PressureFactor; double pressureDelta = endNode.PressureFactor / beginNode.PressureFactor - 1f; double pressureDelta2 = beginNode.PressureFactor / endNode.PressureFactor - 1f; foreach (ContourSegment item in hitContour) { bool flag2 = HitTestStrokeNodes(item, beginNode, endNode, ref result); if (result.IsFull) { return(result); } if (!flag2) { if (!quad.IsEmpty) { flag2 = (item.IsArc ? HitTestQuadCircle(quad, item.Begin + item.Radius, item.Radius) : HitTestQuadSegment(quad, item.Begin, item.End)); } if (!flag2) { if (flag) { flag = (item.IsArc ? (WhereIsVectorAboutArc(endNode.Position - item.Begin - item.Radius, -item.Radius, item.Vector - item.Radius) != HitResult.Hit) : (WhereIsVectorAboutVector(endNode.Position - item.Begin, item.Vector) == HitResult.Right)); } continue; } } flag = false; if (!DoubleUtil.AreClose(result.BeginFIndex, StrokeFIndices.BeforeFirst)) { double num = CalculateClipLocation(item, beginNode, spineVector, pressureDelta); if (num != StrokeFIndices.BeforeFirst && result.BeginFIndex > num) { result.BeginFIndex = num; } } if (!DoubleUtil.AreClose(result.EndFIndex, StrokeFIndices.AfterLast)) { double num2 = CalculateClipLocation(item, endNode, spineVector2, pressureDelta2); if (num2 != StrokeFIndices.BeforeFirst) { num2 = 1.0 - num2; if (result.EndFIndex < num2) { result.EndFIndex = num2; } } } } if (DoubleUtil.AreClose(result.BeginFIndex, StrokeFIndices.AfterLast)) { if (!DoubleUtil.AreClose(result.EndFIndex, StrokeFIndices.BeforeFirst)) { result.BeginFIndex = StrokeFIndices.BeforeFirst; } } else if (DoubleUtil.AreClose(result.EndFIndex, StrokeFIndices.BeforeFirst)) { result.EndFIndex = StrokeFIndices.AfterLast; } if (IsInvalidCutTestResult(result)) { return(StrokeFIndices.Empty); } if (!result.IsEmpty || !flag) { return(result); } return(StrokeFIndices.Full); }
private void CalculateCutLocations(Vector spineVector, Vector hitBegin, Vector hitEnd, double endRadius, double beginRadius, ref StrokeFIndices result) { if (!DoubleUtil.AreClose(result.EndFIndex, StrokeFIndices.AfterLast) && WhereIsNodeAboutSegment(spineVector, hitBegin, hitEnd) == HitResult.Left) { double num = 1.0 - ClipTest(spineVector, endRadius, beginRadius, hitBegin, hitEnd); if (num > result.EndFIndex) { result.EndFIndex = num; } } if (DoubleUtil.AreClose(result.BeginFIndex, StrokeFIndices.BeforeFirst)) { return; } hitBegin -= spineVector; hitEnd -= spineVector; if (WhereIsNodeAboutSegment(-spineVector, hitBegin, hitEnd) == HitResult.Left) { double num2 = ClipTest(-spineVector, beginRadius, endRadius, hitBegin, hitEnd); if (num2 < result.BeginFIndex) { result.BeginFIndex = num2; } } }
internal override StrokeFIndices CutTest(StrokeNodeData beginNode, StrokeNodeData endNode, Quad quad, IEnumerable <ContourSegment> hitContour) { Vector vector = beginNode.IsEmpty ? new Vector(0.0, 0.0) : (beginNode.Position - endNode.Position); if (!_nodeShapeToCircle.IsIdentity) { vector = _nodeShapeToCircle.Transform(vector); } double num = 0.0; double num2 = 0.0; double num3 = _radius * (double)endNode.PressureFactor; double num4 = num3 * num3; if (!beginNode.IsEmpty) { num = _radius * (double)beginNode.PressureFactor; num2 = num * num; } bool flag = true; StrokeFIndices result = StrokeFIndices.Empty; foreach (ContourSegment item in hitContour) { if (!item.IsArc) { Vector vector2 = item.Begin - endNode.Position; Vector vector3 = vector2 + item.Vector; if (!_nodeShapeToCircle.IsIdentity) { vector2 = _nodeShapeToCircle.Transform(vector2); vector3 = _nodeShapeToCircle.Transform(vector3); } bool flag2 = false; if (StrokeNodeOperations.GetNearest(vector2, vector3).LengthSquared < num4) { flag2 = true; if (!DoubleUtil.AreClose(result.EndFIndex, StrokeFIndices.AfterLast)) { result.EndFIndex = StrokeFIndices.AfterLast; if (beginNode.IsEmpty) { result.BeginFIndex = StrokeFIndices.BeforeFirst; break; } if (DoubleUtil.AreClose(result.BeginFIndex, StrokeFIndices.BeforeFirst)) { break; } } } if (!beginNode.IsEmpty && (!flag2 || !DoubleUtil.AreClose(result.BeginFIndex, StrokeFIndices.BeforeFirst)) && StrokeNodeOperations.GetNearest(vector2 - vector, vector3 - vector).LengthSquared < num2) { flag2 = true; if (!DoubleUtil.AreClose(result.BeginFIndex, StrokeFIndices.BeforeFirst)) { result.BeginFIndex = StrokeFIndices.BeforeFirst; if (DoubleUtil.AreClose(result.EndFIndex, StrokeFIndices.AfterLast)) { break; } } } if (beginNode.IsEmpty || (!flag2 && (quad.IsEmpty || !StrokeNodeOperations.HitTestQuadSegment(quad, item.Begin, item.End)))) { if (flag && StrokeNodeOperations.WhereIsVectorAboutVector(endNode.Position - item.Begin, item.Vector) != HitResult.Right) { flag = false; } } else { flag = false; CalculateCutLocations(vector, vector2, vector3, num3, num, ref result); if (result.IsFull) { break; } } } } if (!result.IsFull) { if (flag) { result = StrokeFIndices.Full; } else if (DoubleUtil.AreClose(result.EndFIndex, StrokeFIndices.BeforeFirst) && !DoubleUtil.AreClose(result.BeginFIndex, StrokeFIndices.AfterLast)) { result.EndFIndex = StrokeFIndices.AfterLast; } else if (DoubleUtil.AreClose(result.BeginFIndex, StrokeFIndices.AfterLast) && !DoubleUtil.AreClose(result.EndFIndex, StrokeFIndices.BeforeFirst)) { result.BeginFIndex = StrokeFIndices.BeforeFirst; } } if (IsInvalidCutTestResult(result)) { return(StrokeFIndices.Empty); } return(result); }