Я потратил некоторое время на это, и это оказалось хорошей программой для игры с (thanks to Jerry for great blog post). В конце концов я закончил с небольшим разным решением - чуть ниже.
Если вам нужно подсчитать все круги, вам нужно помнить момент, когда угол изменяется с 360 на 0 и помнит, что был полный круг. В моем примере я помню последний квадрант, и это помогает мне справиться с этой проблемой. Основной код выглядит следующим образом:
private Quadrants currentQuadrant = Quadrants.I;
private Quadrants lastQuadrant = Quadrants.I;
private double lastAngle = 0;
public enum Quadrants { I, IV, III, II } // counterclockwise quadrants
private double CheckAngle(Point touchPoint, Size bounds)
{
// find point position relative to bounds
double valX = touchPoint.X - (bounds.Width/2d);
double valY = (bounds.Height/2d) - touchPoint.Y;
// determine the quadrant and save it
currentQuadrant = (valX >= 0) ?
(valY >= 0) ? Quadrants.I : Quadrants.IV :
(valY >= 0) ? Quadrants.II : Quadrants.III;
double quadrantAngle = Math.Atan(valX/valY) * (180/Math.PI); // calculate angle within quadrant
return currentQuadrant == Quadrants.II ? 360 + quadrantAngle :
currentQuadrant != Quadrants.I ? 180 + quadrantAngle : quadrantAngle;
}
private void Grid_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
double currentAngle = CheckAngle(e.Position, this.RenderSize);
if (Math.Abs(lastAngle - currentAngle) < 1) return; // don't update UI always - performance
if (currentQuadrant == Quadrants.I && lastQuadrant == Quadrants.II) // check for full circle
{ spinNumber++; RaiseProperty("SpinNumber"); }
else if ((currentQuadrant > lastQuadrant + 1)) return; // check if proper movement
// update quadrants and Angle
lastQuadrant = currentQuadrant;
Angle = lastAngle = currentAngle;
}
private void Grid_ManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
{
// reset all things
Angle = lastAngle = spinNumber =0;
currentQuadrant = lastQuadrant = Quadrants.I;
}
и некоторые XAML часть:
<Grid>
<Grid ManipulationMode="All" ManipulationDelta="Grid_ManipulationDelta" ManipulationCompleted="Grid_ManipulationCompleted">
<Ellipse Width="300" Height="300" Fill="Red"/>
<Path Fill="Green" Data="M 0 0 L 50 0 L 100 150 L 0 150 L 50 0 Z" HorizontalAlignment="Center" VerticalAlignment="Center" RenderTransformOrigin="0.5,0.5">
<Path.RenderTransform>
<RotateTransform Angle="{Binding Angle}"/>
</Path.RenderTransform>
</Path>
</Grid>
<TextBlock Text="{Binding AngleTxt}" VerticalAlignment="Bottom" Margin="0,0,0,50" HorizontalAlignment="Center"/>
<TextBlock Text="{Binding SpinNumber}" VerticalAlignment="Bottom" Margin="0,0,0,25" HorizontalAlignment="Center"/>
</Grid>
Обратите внимание, что это будет работать, если вы перемещаете палец, начиная с первого квадранта в направлении по часовой стрелке. Он также нуждается в некоторых дополнительных улучшениях, например, когда вы двигаетесь против часовой стрелки, особенно в зависимости от 0 до 360 градусов.
Я думаю, что в этом случае вам придется отслеживать движение пальца, и как только он пройдет начальную точку вдоль дуги, рассматривайте ее как движение полного круга. – Romasz
@Romasz, это бит, который я не могу понять. :( – Jessica