c# - 何时设置 islargearch UWP
问题描述
我必须设置 IsLArgeArc 但我不能准确地做到这一点。
用户控件.xaml:
<UserControl
x:Class="Pointer_Answer_UWP.RadialSlider"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Pointer_Answer_UWP"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="207"
d:DesignWidth="207">
<Grid>
<Grid x:Name="GridBase" Width="207" Height="207" Background="#FFD7B6B6">
<Ellipse Fill="#FFC7C7C7"/>
<Grid Height="207" Width="207" HorizontalAlignment="Center" VerticalAlignment="Center">
<Path Stroke="#FF34A1ED" StrokeThickness="7" x:Name="arcPath" StrokeEndLineCap="Round" StrokeStartLineCap="Round" RenderTransformOrigin="0.5,0.5">
<Path.RenderTransform>
<CompositeTransform TranslateX="3.5" TranslateY="3.5"/>
</Path.RenderTransform>
<Path.Data>
<PathGeometry>
<PathFigure x:Name="myArcStart" StartPoint="7.612,61.6317">
<ArcSegment x:Name="myArc" IsLargeArc="False" Point="78.3221,197.6221" Size="100,100"/>
</PathFigure>
</PathGeometry>
</Path.Data>
</Path>
</Grid>
<Canvas x:Name="CanvasVolume" Width="207" Height="207" RenderTransformOrigin="0.5,0.5">
<Canvas.RenderTransform>
<CompositeTransform x:Name="CompositePoint" Rotation="0"/>
</Canvas.RenderTransform>
<Ellipse x:Name="VolumePoint" Width="20" Height="20" Fill="#9923678A" PointerPressed="VolumePoint_PointerPressed" Canvas.Top="{x:Bind TopPosition, Mode=OneWay}" Canvas.Left="{x:Bind LeftPosition, Mode=OneWay}"/>
</Canvas>
</Grid>
</Grid>
用户控件.xaml.cs:
public sealed partial class RadialSlider : UserControl, INotifyPropertyChanged
{
private double topPosition = 55.2317;
public double TopPosition
{
get => topPosition;
set
{
topPosition = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(TopPosition)));
}
}
private double leftPosition = 1.112;
public double LeftPosition
{
get => leftPosition;
set
{
leftPosition = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(LeftPosition)));
}
}
public event PropertyChangedEventHandler PropertyChanged;
public RadialSlider()
{
this.InitializeComponent();
}
private void VolumePoint_PointerPressed(object sender, PointerRoutedEventArgs e)
{
RadialSlider radialSlider = this as RadialSlider;
Point puntopressd = e.GetCurrentPoint(CanvasVolume).Position;
PointerEventHandler moved = null;
moved = (s, args) =>
{
CanvasVolume.CapturePointer(e.Pointer);
Point puntomoved = e.GetCurrentPoint(CanvasVolume).Position;
double puntoX = puntomoved.X;
double puntoY = puntomoved.Y;
double raggio = 100;
double halfWidth = CanvasVolume.ActualHeight / 2;
double slashLength = Math.Sqrt((Math.Abs(puntoY - halfWidth) * Math.Abs(puntoY - halfWidth) + (Math.Abs(halfWidth - puntoX) * Math.Abs(halfWidth - puntoX))));
double coordinataX = CanvasVolume.ActualHeight / 2 + ((puntoX - halfWidth) * raggio / slashLength) - VolumePoint.Width / 2;
double coordinataY = puntoY - ((puntoY - halfWidth) * (slashLength - raggio) / slashLength) - VolumePoint.Width / 2;
double angolo = GetAngle(new Point((CanvasVolume.ActualHeight / 2 + ((puntoX - halfWidth) * raggio / slashLength)) - 3.5, (puntoY - ((puntoY - halfWidth) * (slashLength - raggio) / slashLength)) - 3.5), new Size(CanvasVolume.Width, CanvasVolume.Width));
LeftPosition = coordinataX;
TopPosition = coordinataY;
//myArc.IsLargeArc = angolo < 113 ? true : false;
myArc.Point = new Point((CanvasVolume.ActualHeight / 2 + ((puntoX - halfWidth) * raggio / slashLength)) -3.5, (puntoY - ((puntoY - halfWidth) * (slashLength - raggio) / slashLength)) - 3.5);
};
PointerEventHandler released = null;
released = (s, args) =>
{
Point puntoreleas = e.GetCurrentPoint(CanvasVolume).Position;
CanvasVolume.PointerMoved -= moved;
CanvasVolume.PointerReleased -= released;
};
CanvasVolume.PointerMoved += moved;
CanvasVolume.PointerReleased += released;
}
public enum Quadrants : int { nw = 2, ne = 1, sw = 4, se = 3 }
private double GetAngle(Point point, Size size)
{
var X = point.X - (size.Width / 2d);
var Y = size.Height - point.Y - (size.Height / 2d);
var Hypot = Math.Sqrt(X * X + Y * Y);
var Value = Math.Asin(Y / Hypot) * 180 / Math.PI;
var Quadrant = (X >= 0) ? (Y >= 0) ? Quadrants.ne : Quadrants.se : (Y >= 0) ? Quadrants.nw : Quadrants.sw;
switch (Quadrant)
{
case Quadrants.ne: Value = 090 - Value; break;
case Quadrants.nw: Value = 270 + Value; break;
case Quadrants.se: Value = 090 - Value; break;
case Quadrants.sw: Value = 270 + Value; break;
}
return Value;
}
}
如何准确计算何时设置 IsLargeArc 以获得正确结果?我尝试在 ArcSegment 达到 180° 时计算它的角度,但我无法得到正确的结果。
使用 GetAngle 我得到了角度,但我无法正确使用数据。我该如何进行?
感谢帮助。
解决方案
考虑到 360 度的角度环绕,尝试使用 Math.Sin 函数,如下所示。顺便说一句,在这种情况下,要交给 GetAngle 的尺寸应该是 Size(raggio * 2, raggio * 2)。
double angolo = GetAngle(new Point(
(CanvasVolume.ActualHeight / 2 + ((puntoX - halfWidth) * raggio / slashLength)) - 3.5,
(puntoY - ((puntoY - halfWidth) * (slashLength - raggio) / slashLength)) - 3.5
), new Size(raggio * 2, raggio * 2)
);
// BTW, it's also possible to calculate the angle at once with the handy Math.Atan2.
// double angolo = 180.0 - Math.Atan2(puntoX - halfWidth, puntoY - halfWidth) * 180.0 / Math.PI;
myArc.IsLargeArc = Math.Sin((angolo - 113) * Math.PI / 180.0) < 0.0;// ? true : false;
推荐阅读
- html - 托管在 firebase 托管上的 html 页面上的视频无法在 Safari 上运行
- node.js - How to use multiple andWhere with knex in Node app?
- python - 如何获取 Python 列表的切片以组合连续元素?
- r - 如何在 google-collaboration 上安装 rgdal 和/或上传栅格
- javascript - 如何遍历 JSON 模式并将所有值设置为空字符串?
- excel - 如何在 VBA 的 for 循环中索引 excel 工作表函数的参数?
- html - 如何将文本相对于另一个文本的单个字母居中?
- video - 使用ffmpeg按大小和名称和名称拆分视频文件
- r - Survminer,生存包:“survdiff”对数秩和“常规”对数秩测试有什么区别?
- javascript - 邮递员测试是否填写了所需的输入