public TwoFingerGesture(NSSet touches, ARSCNView view, VirtualObject parentObject, VirtualObjectManager manager) : base(touches, view, parentObject, manager) { var tArray = touches.ToArray <UITouch>(); FirstTouch = tArray[0]; SecondTouch = tArray[1]; var firstTouchPoint = FirstTouch.LocationInView(SceneView); var secondTouchPoint = SecondTouch.LocationInView(SceneView); InitialMidpoint = firstTouchPoint.Add(secondTouchPoint).Divide(2f); // Compute the two other corners of the rectangle defined by the two fingers // and compute the points in between. var thirdCorner = new CGPoint(firstTouchPoint.X, secondTouchPoint.Y); var fourthCorner = new CGPoint(secondTouchPoint.X, firstTouchPoint.Y); // Compute points in between. var midpoints = new[] { thirdCorner.Add(firstTouchPoint).Divide(2f), thirdCorner.Add(secondTouchPoint).Divide(2f), fourthCorner.Add(firstTouchPoint).Divide(2f), fourthCorner.Add(secondTouchPoint).Divide(2f), InitialMidpoint.Add(firstTouchPoint).Divide(2f), InitialMidpoint.Add(secondTouchPoint).Divide(2f), InitialMidpoint.Add(thirdCorner).Divide(2f), InitialMidpoint.Add(fourthCorner).Divide(2f) }; // Check if any of the two fingers or their midpoint is touching the object. // Based on that, translation, rotation and scale will be enabled or disabled. var allPoints = new List <CGPoint>(new[] { firstTouchPoint, secondTouchPoint, thirdCorner, fourthCorner, InitialMidpoint }); allPoints.AddRange(midpoints); FirstTouchedObject = allPoints.Select(pt => this.VirtualObjectAt(pt)).Where(vo => vo != null).FirstOrDefault(); if (FirstTouchedObject != null) { ObjectBaseScale = FirstTouchedObject.Scale.X; AllowTranslation = true; AllowRotation = true; InitialDistanceBetweenFingers = (firstTouchPoint.Subtract(secondTouchPoint)).Length(); InitialFingerAngle = Math.Atan2(InitialMidpoint.X, InitialMidpoint.Y); InitialObjectAngle = FirstTouchedObject.EulerAngles.Y; } else { AllowTranslation = false; AllowRotation = false; } }
public static void DrawText(CGContext context, string text, CGPoint position, TextStyle textStyle) { if (string.IsNullOrEmpty(text)) { return; } UIGraphics.PushContext(context); textStyle.Color.SetColor(); var textRect = new CGRect(new CGPoint(), text.StringSize(textStyle.Font)); position = position.Add(textStyle.Offset); textRect = textRect.LocateAtPosition(position, textStyle.Position); text.DrawString(textRect, textStyle.Font); UIGraphics.PopContext(); }
void SetupRings(int itemCount) { // Define some nice colors. var borderColorSelected = UIColor.FromHSBA(0.07f, 0.81f, 0.98f, 1).CGColor; var borderColorNormal = UIColor.DarkGray.CGColor; var fillColorSelected = UIColor.FromHSBA(0.07f, 0.21f, 0.98f, 1); var fillColorNormal = UIColor.White; // We define generators to return closures which we use to define // the different states of our item ring views. Func <RingView, Action> selectedGenerator = (view) => () => { view.Layer.BorderColor = borderColorSelected; view.BackgroundColor = fillColorSelected; }; Func <RingView, Action> normalGenerator = (view) => () => { view.Layer.BorderColor = borderColorNormal; view.BackgroundColor = fillColorNormal; }; CGPoint startPosition = Bounds.GetCenter(); Func <RingView, Action> locationNormalGenerator = (view) => () => { view.Center = startPosition; if (!view.Selected) { view.Alpha = 0; } }; Func <RingView, CGVector, Action> locationFanGenerator = (view, offset) => () => { view.Center = startPosition.Add(offset); view.Alpha = 1; }; // tau is a full circle in radians var tau = NMath.PI * 2; var absoluteRingSegment = tau / 4; var requiredLengthPerRing = RingRadius * 2 + 5; var totalRequiredCirlceSegment = requiredLengthPerRing * (itemCount - 1); var fannedControlRadius = NMath.Max(requiredLengthPerRing, totalRequiredCirlceSegment / absoluteRingSegment); var normalDistance = new CGVector(0, -fannedControlRadius); var scale = UIScreen.MainScreen.Scale; // Setup our item views. for (int index = 0; index < itemCount; index++) { var view = new RingView(Bounds); view.StateClosures [Selected] = selectedGenerator(view); view.StateClosures [Normal] = normalGenerator(view); nfloat angle = index / (nfloat)(itemCount - 1) * absoluteRingSegment; var fan = normalDistance.Apply(MakeRotation(angle)).RoundTo(scale); view.StateClosures [LocationFan] = locationFanGenerator(view, fan); view.StateClosures [LocationOrigin] = locationNormalGenerator(view); AddSubview(view); RingViews.Add(view); var gr = new UITapGestureRecognizer(Tap); view.AddGestureRecognizer(gr); } // Setup the initial selection state. var rv = RingViews [0]; AddSubview(rv); rv.Selected = true; selectedView = rv; UpdateViews(animated: false); }
public static CGPoint MidPoint(this CGPoint self, CGPoint point) { return(self.Add(point).Divide(2f)); }