/// <summary> /// Creates a new instance of <see cref="TangibleObject"/>. /// </summary> /// <param name="point1">The first point.</param> /// <param name="point2">The second point.</param> /// <param name="point3">The third point. This should be the direction point.</param> internal TangibleObject(TouchPoint point1, TouchPoint point2, TouchPoint point3) { Check.NotNull(point1, "point1"); Check.NotNull(point2, "point2"); Check.NotNull(point3, "point3"); // Validate the points if (point1.IsDirectionPoint || point2.IsDirectionPoint) throw new InvalidOperationException("The first two points should not be direction points!"); if (!point3.IsDirectionPoint) throw new InvalidOperationException("No direction point specified!"); Points = new TouchPointCollection(); Points.AddPoint(point1); Points.AddPoint(point2); Points.AddPoint(point3); // Create the bottom line _bottomLine = new TouchLine(point1, point2); // Calculate the top line _topLine = CalculateTopLine(_bottomLine, point3); _topLine.Owner = this; // Set the owner of the points. //Points.ForEach(p => p.Owner = this); foreach (var point in Points) { point.Owner = this; point.Changed += OnPointChanged; } }
/// <summary> /// Gets the min distance to a given point. /// </summary> /// <param name="points">The points.</param> /// <param name="point">The point.</param> /// <returns>a tuple with the first item - the point; and the second item - the distance.</returns> public static Tuple<TouchPoint, double> MinDistanceTo(this IEnumerable<TouchPoint> points, TouchPoint point) { var result = points.Where(p => p != point) .Select(x => new { Distance = MathHelper.Distance(point, x), Point = x, }) .MinBy(x => x.Distance); return result != null ? new Tuple<TouchPoint, double>(result.Point, result.Distance) : null; }
/// <summary> /// Creates a new instance of <see cref="TouchLine"/> by given two points. /// </summary> /// <param name="p1">The first point.</param> /// <param name="p2">The second point.</param> public TouchLine(TouchPoint p1, TouchPoint p2) { Point1 = p1; Point2 = p2; }
/// <summary> /// Invoked when a dependent point has changed in order /// to update the dependency. /// </summary> /// <param name="source">The source of the change.</param> /// <param name="args">The event arguments.</param> void OnDependentPointChanged(TouchPoint source, PointChangedEventArgs args) { Point oldPosition = this._position; Point newPosition = new Point(oldPosition.X + args.DeltaX, oldPosition.Y + args.DeltaY); //this.X = this.X + args.DeltaX; //this.Y = this.Y + args.DeltaY; this._position = newPosition; OnPropertyChanged(() => X); OnPropertyChanged(() => Y); OnChanged(oldPosition, newPosition); }
/// <summary> /// Makes the current point dependent on a given touch point. /// </summary> /// <param name="touchPoint">The touch point.</param> internal void DependsOn(TouchPoint touchPoint) { if (_dependentPoint != null) { _dependentPoint.Changed -= OnDependentPointChanged; _dependentPoint = null; } if (touchPoint != null) { _dependentPoint = touchPoint; _dependentPoint.Changed += OnDependentPointChanged; } }
/// <summary> /// Creates a new instance of <see cref="TouchPoint"/> by given <see cref="PointerPoint"/>. /// </summary> /// <param name="point">The pointer point.</param> /// <returns>new instance of <see cref="TouchPoint"/>.</returns> public static TouchPoint Create(PointerPoint point) { TouchPoint touchPoint = new TouchPoint(point); return touchPoint; }
/// <summary> /// Invoked when a point has changed. /// </summary> /// <param name="source">The source of the change.</param> /// <param name="args">The event arguments.</param> private void OnPointChanged(TouchPoint source, PointChangedEventArgs args) { // Manually update the disconnected point var disconnectedPoint = DisconnectedPoint; // Check whether the disconnectedPoint is not the source of the event, as the event will be raised when the point has just been disconnected. // Furthermore, we need two touch points to update the third disconnected point. if (disconnectedPoint != null && disconnectedPoint != source) { // We need to update one of the other two points that define the bottom line of the tangible object. // One of the known touch points is the source. // Now we need to find the other touch point that has contact. var knownPoint = Points.Single(p => p != source && p != disconnectedPoint); Windows.Foundation.Point reconstructedPoint; Tuple<Windows.Foundation.Point, Windows.Foundation.Point> reconstructedPoints; if (source.IsDirectionPoint) { // We know the direction point (source) and one of the points from the bottom line (knownPoint). // As both points are symmetric we only need to consider one case. reconstructedPoints = MathHelper.GetThirdPointOfTriangle(source, knownPoint, DistanceToDirectionPoint, BottomLineLength); } else { // We have one known point from the bottom line and the direction point. if (disconnectedPoint.IsDirectionPoint) { // We know the points from the bottom line (source, knownPoint). // We search for the direction point. reconstructedPoints = MathHelper.GetThirdPointOfTriangle(source, knownPoint, DistanceToDirectionPoint, DistanceToDirectionPoint); } else { // We know one point from the bottom line (source) and the direction point (knownPoint) reconstructedPoints = MathHelper.GetThirdPointOfTriangle(source, knownPoint, BottomLineLength, DistanceToDirectionPoint); } } // As we have two solutions, we need the one that is closer to the previous value // of the disconnected point. reconstructedPoint = new List<Windows.Foundation.Point>() { reconstructedPoints.Item1, reconstructedPoints.Item2 }.MinDistanceTo(disconnectedPoint); // Update the disconnected point. // NOT WORKING !!! // disconnectedPoint.UpdateDisconnectedPoint(reconstructedPoint.X, reconstructedPoint.Y); } // Update the top line. var directionPoint = Points.Single(p => p.IsDirectionPoint); var bottomLinePoints = Points.Where(p => !p.IsDirectionPoint).ToArray(); if (bottomLinePoints.Count() > 2) throw new InvalidOperationException("The tangible object has unsufficient points."); var topLine = CalculateTopLine(bottomLinePoints[0], bottomLinePoints[1], directionPoint); _topLine.Update(topLine); }
/// <summary> /// Calculates the position of the top line. /// </summary> /// <param name="p1">The first point.</param> /// <param name="p2">The second point.</param> /// <param name="directionPoint">The direction point.</param> /// <returns>the top line.</returns> private Line2D CalculateTopLine(TouchPoint p1, TouchPoint p2, TouchPoint directionPoint) { Line2D topLine = MathHelper.GetParallelLine(p1, p2, directionPoint, TopLineOffset); //TODO Make the top line a little bigger than the bottom line, because we have U-form. return topLine; }
/// <summary> /// Calculates the position of the top line. /// </summary> /// <param name="bottomLine">The bottom line.</param> /// <param name="directionPoint">The direction point.</param> /// <returns>the top line.</returns> private Line2D CalculateTopLine(TouchLine bottomLine, TouchPoint directionPoint) { return CalculateTopLine(bottomLine.Point1, bottomLine.Point2, directionPoint); }
void OnTouchPointReleased(TouchPoint touchPoint) { _points.Remove(touchPoint); if (!_userContactsInitialized) { ShowContacts(); _userContactsInitialized = true; } // Stop the timer when the point looses contact // TryStopTimer(touchPoint); }
/// <summary> /// Updates the position of an TangibleObject /// </summary> /// <param name="touchPoint">The touch point.</param> void OnTouchPointMoved(TouchPoint touchPoint) { if (touchPoint == null) return; if (touchPoint.BelongsToTangibleObject && touchPoint.IsInContact && touchPoint.IsDirectionPoint) { var tangibleObject = touchPoint.Owner; var controller = GetController(tangibleObject); // Update the position of the control var tangibleObjectControl = controller.TangibleObjectControl; tangibleObjectControl.SetPosition(touchPoint.Position.X, touchPoint.Position.Y); tangibleObjectControl.SetRotation(MathHelper.GetTangibleRotation(touchPoint.Owner)); // Show the filter control when we are with the tangible object over a corner // TryShowFilterControl(touchPoint, controller); } }
/// <summary> /// Raises the <see cref="TouchPointReleased"/> event. /// </summary> /// <param name="point">The released point.</param> protected virtual void OnTouchPointReleased(TouchPoint point) { var handler = TouchPointReleased; handler?.Invoke(point); }