/// <summary> /// Creates the diagonal Guide Paths /// </summary> /// <param name="pixel"></param> private void SuggestGuidePaths(SKPoint pixel) { float x = pixel.X; float y = pixel.Y; var pathList = new List <BondPath>(); const float len = 200; const double ang = 0.5235987756; // 30 degrees from horizontal to get 120 deg diagonals for hexagons var path = new BondPath(); path.MoveTo(x, y); path.LineTo(x + len * (float)Math.Cos(ang), y + len * (float)Math.Sin(ang)); pathList.Add(path); path = new BondPath(); path.MoveTo(x, y); path.LineTo(x + len * (float)Math.Cos(ang), y - len * (float)Math.Sin(ang)); pathList.Add(path); path = new BondPath(); path.MoveTo(x, y); path.LineTo(x - len * (float)Math.Cos(ang), y + len * (float)Math.Sin(ang)); pathList.Add(path); path = new BondPath(); path.MoveTo(x, y); path.LineTo(x - len * (float)Math.Cos(ang), y - len * (float)Math.Sin(ang)); pathList.Add(path); guidePaths.Add(pixel, pathList); }
/// <summary> /// Creates the vertical and horizontal Guide Paths /// </summary> /// <param name="pixel"></param> private void SuggestAltGuidePaths(SKPoint pixel) { float x = pixel.X; float y = pixel.Y; var pathList = new List <BondPath>(); const float len = 200; var path = new BondPath(); path.MoveTo(x, y); path.LineTo(x, y + len); pathList.Add(path); path = new BondPath(); path.MoveTo(x, y); path.LineTo(x, y - len); pathList.Add(path); path = new BondPath(); path.MoveTo(x, y); path.LineTo(x + len, y); pathList.Add(path); path = new BondPath(); path.MoveTo(x, y); path.LineTo(x - len, y); pathList.Add(path); guidePaths[pixel].AddRange(pathList); }
/// <summary> /// Processes touch input /// </summary> /// <param name="sender"></param> /// <param name="args"></param> void TouchEffect_OnTouchAction(object sender, TouchActionEventArgs args) { switch (args.Type) { // An individual press // If canvas is blank then it purely suggests the guide paths // If the canvas is not blank then the touch only registers if it hits on an existing atom case TouchActionType.Pressed: if (!inProgressPaths.ContainsKey(args.Id)) { guidePaths.Clear(); BondPath path = new BondPath(); var pixel = ConvertToPixel(args.Location); if (completedPaths.Count > 0) { foreach (var pth in completedPaths) { if (SKPoint.Distance(pth[0], pixel) < 50) { pixel = pth[0]; SuggestGuidePaths(pixel); SuggestAltGuidePaths(pixel); break; } if (SKPoint.Distance(pth.LastPoint, pixel) < 50) { pixel = pth.LastPoint; SuggestGuidePaths(pixel); SuggestAltGuidePaths(pixel); break; } } GuidePathTrim(pixel); } path.MoveTo(pixel); inProgressPaths.Add(args.Id, path); if (completedPaths.Count == 0) { SuggestGuidePaths(pixel); SuggestAltGuidePaths(pixel); } canvasView.InvalidateSurface(); } break; // Drag the line to the end of the template line and then it becomes a 'completed line' case TouchActionType.Moved: if (inProgressPaths.ContainsKey(args.Id)) { BondPath path = inProgressPaths[args.Id]; var firstPoint = path[0]; path.Rewind(); path.MoveTo(firstPoint); path.LineTo(ConvertToPixel(args.Location)); if (guidePaths.ContainsKey(firstPoint)) { BondPath linqPath = guidePaths[firstPoint] .FirstOrDefault(pth => SKPoint.Distance(pth.LastPoint, path.LastPoint) < 30); if (linqPath != null) { guidePaths.Remove(linqPath[0]); linqPath.Order = BondOrderFromPicker(); completedPaths.Add(linqPath); undoStack.Push("path"); MakeNewPathFromPoint(args, linqPath.LastPoint); SuggestGuidePaths(linqPath.LastPoint); SuggestAltGuidePaths(linqPath.LastPoint); GuidePathTrim(linqPath.LastPoint); } } canvasView.InvalidateSurface(); } break; case TouchActionType.Released: if (inProgressPaths.ContainsKey(args.Id)) { inProgressPaths.Remove(args.Id); canvasView.InvalidateSurface(); } break; case TouchActionType.Cancelled: if (inProgressPaths.ContainsKey(args.Id)) { inProgressPaths.Remove(args.Id); canvasView.InvalidateSurface(); } break; } }