【问题标题】:How to get the total rotation angle by one finger touch in WinRT?如何在WinRT中通过一根手指触摸获得总旋转角度?
【发布时间】:2015-04-11 05:36:10
【问题描述】:

我正在尝试通过关注Jerry's tutorial 进行拨号控制。因为GetAngle方法是基于触摸点的位置,所以计算出的角度总是等于或小于360°。但我需要的是,如果我将结旋转两个半圈,我想得到900° (360°*2 + 180°)

我知道e.Cumulative.RotationeManipulationDeltaRoutedEventArgs)可以给我总旋转角度,但看起来旋转只能由两个手指触发。

我在这里错过了一些简单的解决方案吗?

【问题讨论】:

  • 我认为在这种情况下,您必须跟踪手指的运动,一旦它沿着弧形路径通过起点,就将其视为整圈运动。
  • @Romasz,这是我想不通的地方。 :(

标签: xaml windows-8 windows-runtime windows-phone-8.1 windows-8.1


【解决方案1】:

我在这方面花了一些时间,结果证明这是一个不错的程序 (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 度。

【讨论】:

  • 谢谢!!使用象限非常棒,这足以让我前进。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-02
  • 1970-01-01
  • 2014-09-24
相关资源
最近更新 更多