static public object Cropped(this Stroq stroke, Stroq balance, CropTest test) { object sel = null; DictLookup dict = null; if (!stroke.Property.Exists(CROP)) { dict = new DictLookup(); stroke.Property[CROP] = dict; } else { dict = (DictLookup)stroke.Property[CROP]; } if (dict.ContainsKey(test)) { sel = dict[test]; } else { sel = test(stroke, balance); dict.Add(test, sel); } return(sel); }
static public object ScribbledOver(this Stroq stroke, ScribbleTest test) { object sel = null; DictLookup dict = null; if (!stroke.Property.Exists(SCRIBBLE)) { dict = new DictLookup(); stroke.Property[SCRIBBLE] = dict; } else { dict = (DictLookup)stroke.Property[SCRIBBLE]; } if (dict.ContainsKey(test)) { sel = dict[test]; } else { sel = test(stroke); dict.Add(test, sel); } return(sel); }
static public bool IsInsertion(this Stroq stroke) { if (!stroke.Property.Exists(TEXT)) { stroke.Property[TEXT] = insertionCaret(stroke); } return((bool)stroke.Property[TEXT]); }
static public Dir IsDoubleHitch(this Stroq stroke) { if (!stroke.Property.Exists(DLOOP)) { stroke.Property[DLOOP] = doubleHitch(stroke); } return((Dir)stroke.Property[DLOOP]); }
static public int IsLeftRight(this Stroq stroke) { if (!stroke.Property.Exists(UNDO)) { stroke.Property[UNDO] = leftRightHook(stroke); } return((int)stroke.Property[UNDO]); }
static public bool IsDoubleLoop(this Stroq stroke) { if (!stroke.Property.Exists(DLOOP)) { stroke.Property[DLOOP] = doubleLoop(stroke); } return((bool)stroke.Property[DLOOP]); }
static public bool IsTap(this Stroq stroke) { if (!stroke.Property.Exists(IS_TAP)) { bool tap = stroke.GetBounds().MaxDim < 15; stroke.Property[IS_TAP] = tap; } return((bool)stroke.Property[IS_TAP]); }
static public bool IsCrop(this Stroq stroke) { if (stroke.Cusps().Length == 3 && stroke.Cusps().Straightness(0, 1) < 0.15 & stroke.Cusps().Straightness(1, 2) < 0.15 && Math.Abs(stroke.Cusps().inSeg(1).Direction.UnsignedAngle(stroke.Cusps().outSeg(1).Direction) - Math.PI / 2) < Math.PI / 4) { return(true); } return(false); }
/// <summary> /// Process a stroke sequentially through each gesture recognizer, terminating only /// if a gesture is completely recognized. An event is fired when a gesture is matched. /// The method returns whether the stroke completed a gesture, is potentially part of a /// multi-stroke gesture, or if it is not part of any gesture. /// </summary> /// <param name="s"></param> /// <returns></returns> public Result Process(Stroq s) { // try to find a completed gesture foreach (Gesture g in Gestures) { Result r = g.Process(this, s, true, _pending); if (r == Result.Recognized) { _pending.Add(s); fireGesture(g); return(Result.Recognized); } } // pending gesture strokes -> real strokes if they weren't completed // the current policy is that we can have no more than two-stroke gestures. // so if we have a partial match or no match at all, we need to flush out // all the pending strokes (which for now can be at most 1 stroke). foreach (Stroq ps in _pending) { if (StrokeUnrecognizedEvent != null) { StrokeUnrecognizedEvent(this, ps); } } _pending.Clear(); // try to find a new (or new partial)gesture foreach (Gesture g in Gestures) { Result r = g.Process(this, s, false, _pending); if (r != Result.Unrecognized) { // save the stroke if a multi-stroke gesture is pending. s.BackingStroke.DrawingAttributes.Color = GestureStrokeIntermediateColor; _pending.Add(s); if (r == Result.Recognized) { fireGesture(g); } else { Children.Add(s); } return(r); } } // gesture stroke -> real stroke if nothing matched it Children.Clear(); if (StrokeUnrecognizedEvent != null) { StrokeUnrecognizedEvent(this, s); } return(Result.Unrecognized); }
static bool insertionCaret(Stroq caret) { double dist = (caret.Cusps()[1].dist / caret.Cusps().Distance - 0.5); bool isCaret = caret.Cusps().Length == 3 && Math.Abs(caret.Cusps()[1].dist / caret.Cusps().Distance - 0.5) < .1 && caret.Cusps().Straightness(0, 1) < 0.15 && caret.Cusps().Straightness(1, 2) < 0.15 && caret.Cusps().inSeg(1).Direction.UnsignedAngle(new Vec(0, -1)) < Math.PI / 4 && caret.Cusps().inSeg(1).Direction.UnsignedAngle(-caret.Cusps().outSeg(1).Direction) < Math.PI / 4; return(isCaret); }
public StroqElement(Stroq stroq) { _dv = new DrawingVisual(); _stroq = stroq; _stroq.PointChanged += _stroq_PointChanged; _stroq.PointsCleared += _stroq_PointsCleared; _stroq.PointsModified += _stroq_PointsModified; _stroq.BackingStroke.DrawingAttributes.AttributeChanged += new System.Windows.Ink.PropertyDataChangedEventHandler(DrawingAttributes_AttributeChanged); Redraw(); AddVisualChild(_dv); }
static public bool BalancedCrops(this Stroq crop1, Stroq crop2) { if (crop2 != null && (Math.Sign(crop1.Cusps()[1].curvature) == Math.Sign(crop2.Cusps()[1].curvature) || ((crop1.Cusps().outSeg(1).Direction.Normal().Dot(crop2.Cusps().inSeg(1).Direction.Normal()) < -0.5) && (crop1.Cusps().inSeg(1).Direction.Normal().Dot(crop2.Cusps().outSeg(1).Direction.Normal()) < -0.5)))) { return(false); } return(true); }
static public bool IsFlick(this Stroq stroke) { if (!stroke.Property.Exists(IS_FLICK)) { bool flick = stroke.Cusps().Length == 2 && stroke.Cusps().Straightness(0, 1) < 0.15 && stroke.Cusps().Distance > 20 && stroke.Count * 16 < 353 && (stroke.Cusps()[1].pt - stroke.Cusps()[0].pt).Normal().Dot(new Vec(1, -1).Normal()) > 0.65; stroke.Property[IS_FLICK] = flick; } return((bool)stroke.Property[IS_FLICK]); }
static int leftRightHook(Stroq caret) { Pt endpt = Pt.Avg(caret[0], caret[-1]); int dir = (caret.Cusps().Length == 3 && Math.Abs(caret.Cusps()[1].dist / caret.Cusps().Distance - 0.5) < .1 && caret.Cusps().Straightness(0, 1) < 0.15 && caret.Cusps().Straightness(1, 2) < 0.15 && caret.Cusps().inSeg(1).Direction.UnsignedAngle(-caret.Cusps().outSeg(1).Direction) < Math.PI / 8) ? (caret.Cusps()[1].pt - endpt).UnsignedAngle(new Vec(1, 0)) < Math.PI / 6 ? 1 : ((caret.Cusps()[1].pt - endpt).UnsignedAngle(new Vec(-1, 0)) < Math.PI / 6 ? -1 : 0) : 0; return(dir); }
public Gesturizer.Result Process(Gesturizer g, Stroq s, bool onlyPartial, List <Stroq> prev) { if (onlyPartial) { return(Gesturizer.Result.Unrecognized); } if (Test(s)) { return(Gesturizer.Result.Recognized); } return(Gesturizer.Result.Unrecognized); }
static public bool IsLasso(this Stroq stroke) { double threshold = stroke.GetBounds().MaxDim * .2; bool canBeLasso = false; for (int i = stroke.Count - 1; !canBeLasso && i > Math.Max(stroke.Count / 2, stroke.Cusps()[-2].index); i--) { if ((stroke[i] - stroke[0]).Length < threshold) { canBeLasso = true; // the lasso has returned close enough to the starting point to make it a lasso } } return(canBeLasso); }
static public bool IsChar(this Stroq stroke, string charset) { System.Windows.Ink.InkAnalyzer ia = new InkAnalyzer(); ia.AddStroke(stroke.BackingStroke); //AnalysisHintNode node = ia.CreateAnalysisHint(); //node.Factoid = "IS_ONECHAR"; //node.CoerceToFactoid = true; //node.Location.MakeInfinite(); AnalysisStatus astat = ia.Analyze(); string reco = ia.GetRecognizedString(); Console.WriteLine("Recognized:<" + reco + ">"); if (astat.Successful && reco != "Other") { return(charset.Contains(reco[0])); } return(false); }
protected override void OnStylusUp(StylusEventArgs e) { base.OnStylusUp(e); // TJC: only take in stylus ink, not multitouch bool isStylus = e.StylusDevice.Id == MyRend.STYLUS_ID || e.StylusDevice.StylusButtons.Count == 2; // tip and barrel if (!isStylus) { _touchCount--; //System.Console.WriteLine("UP TC: " + _touchCount + " " + _maxTouches); //if (_maxTouches > 0) return; // TJC: test // reset max touch once we hit 0 if (_touchCount <= 0) { _maxTouches = 0; } } // Release stylus capture. if (Stylus.Captured == this) // bcz: uncapturing the stylus will uncapture the mouse. However, widgets like SelectionFeedback may have Captured just the Mouse and won't get their Up events - so don't uncapture unless the captured object is 'this' { Stylus.Capture(null); } if (_stylusPoints == null) { return; } _stylusPoints.Add(e.GetStylusPoints(this, _stylusPoints.Description)); Stroke stroke = new Stroke(_stylusPoints); stroke.DrawingAttributes = _dynamicRenderer.DrawingAttributes.Clone(); Stroq s = new Stroq(stroke); if (KeepStroqs) { _stroqs.Add(s); } _stylusPoints = null; RaiseStroqCollectedEvent(s, !isStylus || e.StylusDevice.SwitchState(InqUtils.BarrelSwitch) == StylusButtonState.Down); }
static bool doubleLoop(Stroq s) { int closeInd = 0; double nearest = double.MaxValue; Pt first = s[0]; for (int i = s.Count / 4; i < 3 * s.Count / 4; i++) { if ((s[i] - first).Length < nearest) { nearest = (s[i] - first).Length; closeInd = i; } } if (nearest < s.GetBounds().MaxDim *.4 && closeInd > 2 && closeInd < s.Count - 2) { List <Pt> clipped = new List <Pt>(s.Select <Pt, Pt>((Pt p) => p)); List <Pt> clipped2 = new List <Pt>(s.Select <Pt, Pt>((Pt p) => p)); clipped.RemoveRange(closeInd, s.Count - closeInd); clipped2.RemoveRange(0, closeInd); Rct r1 = Rct.Null; Rct r2 = Rct.Null; foreach (Pt p in clipped) { r1 = r1.Union(p); } foreach (Pt p in clipped2) { r2 = r2.Union(p); } Rct r3 = r1.Union(r2); Rct inter = r1.Intersection(r2); if (isCircular(clipped.ToArray()) && isCircular(clipped2.ToArray()) && inter.Width / (float)r1.Width > 0.5 && inter.Height / (float)r1.Height > 0.5 && inter.Width / (float)r2.Width > 0.5 && inter.Height / (float)r2.Height > 0.5 && inter.Width / (float)r3.Width > 0.5 && inter.Height / (float)r3.Height > 0.5) { return(true); } } return(false); }
static public bool IsCircle(this Stroq stroke) { if (!stroke.Property.Exists(IS_CIRCLE)) { bool circle = (stroke[0] - stroke[-1]).Length / stroke.GetBounds().MaxDim < .2; for (int i = 1; i < stroke.Cusps().Length - 1 && circle; i++) { if (Math.Abs(stroke.Cusps()[i].curvature) > 0.6) { circle = false; } if (Math.Sign(stroke.Cusps()[i].curvature) != Math.Sign(stroke.Cusps()[i - 1].curvature)) { circle = false; } } stroke.Property[IS_CIRCLE] = circle; } return((bool)stroke.Property[IS_CIRCLE]); }
static Dir doubleHitch(Stroq s) { if (s.Cusps().Length == 4 && s.Cusps().Straightness() < zStraightnessTolerance) { Vec dir = (s[-1] - s[0]).Normal(); double dx = dir.SignedAngle(Vec.Xaxis); double ndx = dir.SignedAngle(-Vec.Xaxis); if (dir.X > 0.3) { if (dx > .3) { return(Dir.NE); } else if (dx < -.3) { return(Dir.SE); } else { return(Dir.E); } } else if (dir.X < 0.3) { if (ndx < -.3) { return(Dir.NW); } else if (ndx > .3) { return(Dir.SW); } else { return(Dir.W); } } } return(Dir.None); }
static public object Lassoed(this Stroq stroke, LassoTest test) { object sel = null; DictLookup dict = null; if (!stroke.Property.Exists(LASSO)) { dict = new DictLookup(); stroke.Property[LASSO] = dict; } else { dict = (DictLookup)stroke.Property[LASSO]; } if (dict.ContainsKey(test)) { sel = dict[test]; } else { double threshold = stroke.GetBounds().MaxDim * .2; Stroq lasso = stroke; // truncate the lasso where it retraces closest to its starting point. for (int i = stroke.Count - 1; i > Math.Max(stroke.Count / 2, stroke.Cusps()[-2].index); i--) { if ((stroke[i] - stroke[0]).Length < threshold) { List <Pt> lassoPts = new List <Pt>(); for (int j = 0; j < i; j++) { lassoPts.Add(stroke[j]); } lasso = new Stroq(lassoPts.ToArray()); } } sel = test(lasso); dict.Add(test, sel); } return(sel); }
public Gesturizer.Result Process(Gesturizer g, Stroq s, bool onlyPartial, List <Stroq> prev) { if (OneStroke) { if (onlyPartial) { return(Gesturizer.Result.Unrecognized); } if (Test1(s)) { return(Gesturizer.Result.Recognized); } return(Gesturizer.Result.Unrecognized); } else { if (_text != null) { ClearText(g); } if (onlyPartial && prev.Count == 1 && Test1(prev[0]) && Test2(s, prev[0])) { return(Gesturizer.Result.Recognized); } if (!onlyPartial && Test1(s)) { if (g.Canvas != null) { AddText(g, s.GetBounds().Left, s.GetBounds().Top); } return(Gesturizer.Result.Partial); } } return(Gesturizer.Result.Unrecognized); }
protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e) { base.OnMouseLeftButtonUp(e); Mouse.Capture(null); // If a stylus generated this event, return. if (e.StylusDevice != null || _stylusPoints == null || _stylusPoints.Count == 0) { return; } Point pt = e.GetPosition(this); //_stylusPoints.Add(new StylusPoint(pt.X, pt.Y)); Stroke stroke = new Stroke(_stylusPoints); stroke.DrawingAttributes = _dynamicRenderer.DrawingAttributes.Clone(); Stroq s = new Stroq(stroke); if (KeepStroqs) { _stroqs.Add(s); } _stylusPoints = null; RaiseStroqCollectedEvent(s, false); }
static bool isCircular(Pt[] clippepts) { Stroq tempStroke = new Stroq(clippepts); Cusps set = tempStroke.Cusps(); if (set.SelfIntersects.Count > 4) { return(false); } if (set.Distance > 1.25 * (tempStroke.GetBounds().Width *2 + tempStroke.GetBounds().Height *2)) { return(false); } for (int i = 1; i < set.Length; i++) { if (Math.Abs(set[i].curvature) > .75) { return(false); } } double d = (tempStroke[-1] - tempStroke[0]).Length / tempStroke.GetBounds().MaxDim; return(d < 0.75); }
protected void _stroq_PointChanged(Stroq s, int i) { Redraw(); }
protected void _stroq_PointsCleared(Stroq s) { Redraw(); }
protected void _stroq_PointsModified(Stroq s, Mat?m) { Redraw(); }
private bool ScribbleDelete(Stroke stroke) { starPadSDK.Inq.Stroq stroq = new starPadSDK.Inq.Stroq(stroke); bool canBeScribble = stroq.OldPolylineCusps().Length > 4; if (stroq.OldPolylineCusps().Length == 4) { int[] pcusps = stroq.OldPolylineCusps(); Deg a1 = fpdangle(stroq[0], stroq[pcusps[1]], stroq[pcusps[2]] - stroq[pcusps[1]]); Deg a2 = fpdangle(stroq[pcusps[1]], stroq[pcusps[1]], stroq[pcusps[3]] - stroq[pcusps[1]]); if (a1 < 35 && a2 < 35) canBeScribble = stroq.BackingStroke.HitTest(stroq.ConvexHull().First(), 1); } if (canBeScribble) { IEnumerable<starPadSDK.Geom.Pt> hull = stroq.ConvexHull(); List<Point> hullTemp = new List<Point>(); foreach (starPadSDK.Geom.Pt pt in hull) { hullTemp.Add(new Point(pt.X, pt.Y)); } StrokeCollection stks = this.Strokes.HitTest(hullTemp, 50); if (stks.Count > 1) { //inqCanvas.Stroqs.Remove(stqs); this.Strokes.Remove(stks); if (stks.Contains(stroke)) { stks.Remove(stroke); } this.Strokes.Remove(stroke); _inkAnalyzer.RemoveStrokes(stks); // AnalyzedRegion.Strokes.Remove(stks); } //if (this.Strokes.Contains(stroke)) //{ //{ // this.Strokes.Remove(stroke); //AnalyzedRegion.Strokes.Remove(stroke); //} this.ShowInkAnalysisFeedback = false; return true; } return false; }
private bool ScribbleDelete(Stroke stroke) { starPadSDK.Inq.Stroq stroq = new starPadSDK.Inq.Stroq(stroke); bool canBeScribble = stroq.OldPolylineCusps().Length > 4; if (stroq.OldPolylineCusps().Length == 4) { int[] pcusps = stroq.OldPolylineCusps(); Deg a1 = fpdangle(stroq[0], stroq[pcusps[1]], stroq[pcusps[2]] - stroq[pcusps[1]]); Deg a2 = fpdangle(stroq[pcusps[1]], stroq[pcusps[1]], stroq[pcusps[3]] - stroq[pcusps[1]]); if (a1 < 35 && a2 < 35) canBeScribble = stroq.BackingStroke.HitTest(stroq.ConvexHull().First(), 1); } if (canBeScribble) { //BOKANG bool removeCurrentStroke = CheckRemoveGate(stroke); IEnumerable<starPadSDK.Geom.Pt> hull = stroq.ConvexHull(); List<Point> hullTemp = new List<Point>(); foreach (starPadSDK.Geom.Pt pt in hull) { hullTemp.Add(new Point(pt.X, pt.Y)); } StrokeCollection stks = circuitInkCanvas.Strokes.HitTest(hullTemp, 50); //StroqCollection stqs = inqCanvas.Stroqs.HitTest(hull, 1); if (stks.Count > 1) { //inqCanvas.Stroqs.Remove(stqs); circuitInkCanvas.Strokes.Remove(stks); if (stks.Contains(stroke)) { stks.Remove(stroke); } if(circuitInkCanvas.Strokes.Contains(stroke)) { circuitInkCanvas.Strokes.Remove(stroke); } //inqCanvas.Stroqs.Remove(stroq); return true; } if (removeCurrentStroke) { if(circuitInkCanvas.Strokes.Contains(stroke)) { circuitInkCanvas.Strokes.Remove(stroke); } } } return false; }
protected void RaiseStroqCollectedEvent(Stroq s, bool rightButton) { StroqCollectedEventArgs evtargs = new StroqCollectedEventArgs(StroqCollectedEvent, s, rightButton); RaiseEvent(evtargs); }
public StroqCollectedEventArgs(RoutedEvent revt, Stroq s, bool rightbutton) : base(revt) { Stroq = s; RightButton = rightbutton; }