Silverlight实用窍门系列:29.Silverlight碰撞测试、检测自定义控件碰撞,雷达扫描图之扫描雷达点状态【附带源码实例】

简介:

雷达扫描图中当雷达指针转动扫描到某一个点上的时候,判断这个点的CPU值是否已经超过60的警戒位置如果超过将此点设置为红色。

        在Silverlight中我们的雷达指针是一直在做圆运动的,我们要随时检测雷达指针的位置,以及雷达是否碰撞到一个Device设备了。如果碰撞到了,就检测设备CPU值为多少?在这里我们需要解决两个问题。第一、如何随时观测雷达指针的当前位置?第二、如何检测雷达指针是否碰撞接触到了设备点?

        针对第一个问题,需要做以下处理:

             •在本例中使用Timer控件,每隔50毫秒检测一次当前的雷达指针控件位置

             •雷达指针的位置根据检测当前雷达指针旋转角度的正余弦函数得到左上角点的X、Y位置,分别加上宽和高得到右下角点的位置。

             •在本实例中的碰撞检测函数是根据国外友人Andy的两个函数改编而来的,UserControlBounds函数里面获取Point的方式有所不同。

        针对第二个问题,我们需要做以下处理:

             •根据雷达指针的左上角和右下角的两个点的位置构造一个Rect结构A(注意Rect结构描述矩形的宽高和原点),然后同理根据Device自定义控件构造一个Rect结构。

             •检测者A、B两个Rect是否重合,如果重合则进行像素级别的对比是否碰撞接触在一起。

             •因为有很多个设备点,所以需要循环检测每一个设备点在某一个时间点是否和雷达指针碰撞。

        本篇实例源码基于上一节所述,本节中将雷达指针单独制作成为一个自定义控件,另外为设备自定义控件增加了一个属性IsOutStrip(设置如果超过警戒值则为红色),现在我们来看看本篇关键源码:

复制代码
  
  
public MainPage()
{
InitializeComponent();

AddCanvasTransform();
}
RandarPointer rpointer
= new RandarPointer();
public void AddCanvasTransform()
{


AddDevice();
// 设置一个50毫秒启动一次的定时器
time = new Timer(CheckIsContent, rpointer, 0 , 50 );


}
private void AddDevice()
{
#region 添加闪动的设备
LayoutRoot.Children.Clear();
// 添加雷达指针
LayoutRoot.Children.Add(rpointer);
for ( int i = 0 ; i < 15 ; i ++ )
{
Device dev
= new Device();
// 设置X、Y坐标和Z层次
dev.SetValue(Canvas.TopProperty, dev.Y);
dev.SetValue(Canvas.LeftProperty, dev.X);

// 设置 dev.Tag为控件的左上角的点坐标和右下角的点坐标
double DevRight = dev.X + 16 ;
double DevButtom = dev.Y + 16 ;
dev.SetValue(Canvas.ZIndexProperty,
600 );
dev.Tag
= dev.X + " | " + dev.Y + " | " + DevRight + " | " + DevButtom;
LayoutRoot.Children.Add(dev);
}
#endregion
}
// 添加一个Timer定时器检测当前的指针的位置。
Timer time;
public void CheckIsContent( object state)
{
this .rpointer.Dispatcher.BeginInvoke( new labelDelegete(UpdateLab));


}
public delegate void labelDelegete();
public void UpdateLab()
{
Rectangle rectangle
= rpointer.FindName( " rectangle " ) as Rectangle;
// 获取到当前雷达指针的左上角点的位置和右下角点的位置,赋值给Tag
double top = - Math.Sin(rpointer.rTransform.Angle) * 253 + 300 ;
double left = - Math.Cos(rpointer.rTransform.Angle) * 253 + 300 ;
double right = 300 ;
double buttom = 300 ;
rpointer.Tag
= left + " | " + top + " | " + right + " | " + buttom;

// 循环获取所有的Device控件的位置和当前时间雷达指针是否碰撞
foreach (UIElement ui in LayoutRoot.Children)
{
Device device
= ui as Device;
if (device != null )
{
Rectangle rectangleblue
= device.Rectangleblue;
// 检测雷达指针是否碰撞到设备,
if (CheckCollision(device, rectangleblue, rpointer, rectangle))
{
// 检测设备CPU占用值是否大于60%,如果大于则报警
if (device.Value > 60 )
{
// 让其显示为红色
device.IsOutStrip = true ;
}
}
}
}
}
/// <summary>
/// 检查控件的位置是否碰撞在一起
/// </summary>
/// <param name="control1"> 第一用户控件 </param>
/// <param name="controlElem1"> 第一用户控件内部需要检测是否碰撞的控件 </param>
/// <param name="control2"> 第二用户控件 </param>
/// <param name="controlElem2"> 第二用户控件内部需要检测是否碰撞的控件 </param>
/// <returns></returns>
private bool CheckCollision(FrameworkElement control1, FrameworkElement controlElem1, FrameworkElement control2, FrameworkElement controlElem2)
{
// 创建两个Rect结构
Rect rect1 = UserControlBounds(control1);
Rect rect2
= UserControlBounds(control2);

// 检测这两个Rect结构是否重合
rect1.Intersect(rect2);
if (rect1 == Rect.Empty)
{
// no collision - GET OUT!
return false ;
}
else
{
bool bCollision = false ;
Point ptCheck
= new Point();

// 更精准的像素级别的碰撞对比
for ( int x = Convert.ToInt32(rect1.X); x < Convert.ToInt32(rect1.X + rect1.Width); x ++ )
{
for ( int y = Convert.ToInt32(rect1.Y); y < Convert.ToInt32(rect1.Y + rect1.Height); y ++ )
{
ptCheck.X
= x;
ptCheck.Y
= y;

List
< UIElement > hits = System.Windows.Media.VisualTreeHelper.FindElementsInHostCoordinates(ptCheck, control1) as List < UIElement > ;
if (hits.Contains(controlElem1))
{
// we have a hit on the first control elem, now see if the second elem has a similar hit
List < UIElement > hits2 = System.Windows.Media.VisualTreeHelper.FindElementsInHostCoordinates(ptCheck, control2) as List < UIElement > ;
if (hits2.Contains(controlElem2))
{
bCollision
= true ;
break ;
}
}
}
if (bCollision) break ;
}
return bCollision;
}
}
/// <summary>
/// 根据需要检测的控件的坐标位置,绘制出需要检测控件的副本Rect控件
/// </summary>
/// <param name="control"></param>
/// <returns></returns>
public Rect UserControlBounds(FrameworkElement control)
{
// 重新创建一个Rect结构。
string [] PointDirect = control.Tag.ToString().Split( ' | ' );
Point ptTopLeft
= new Point(Convert.ToDouble(PointDirect[ 0 ]), Convert.ToDouble(PointDirect[ 1 ]));
Point ptBottomRight
= new Point(Convert.ToDouble(PointDirect[ 2 ]), Convert.ToDouble(PointDirect[ 3 ]));

return new Rect(ptTopLeft, ptBottomRight);
}
复制代码

        本实例采用VS2010+Silverlight编写,如需源码点击 SLRandarHitTest.rar  下载,点击下图可查看Silverlight运行效果:

目录
打赏
0
0
0
0
52
分享
相关文章
深入体验阿里云通义灵码:测试与实例展示
阿里云通义灵码是一款强大的代码生成工具,支持自然语言描述需求,快速生成高质量代码。它在测试、代码质量和用户体验方面表现出色,能够高效地生成 Python 和 Java 等语言的代码,助力开发者提升开发效率和代码质量。无论是新手还是资深开发者,都能从中受益匪浅。
深入体验阿里云通义灵码:测试与实例展示
实例分割笔记(一): 使用YOLOv5-Seg对图像进行分割检测完整版(从自定义数据集到测试验证的完整流程)
本文详细介绍了使用YOLOv5-Seg模型进行图像分割的完整流程,包括图像分割的基础知识、YOLOv5-Seg模型的特点、环境搭建、数据集准备、模型训练、验证、测试以及评价指标。通过实例代码,指导读者从自定义数据集开始,直至模型的测试验证,适合深度学习领域的研究者和开发者参考。
2037 3
实例分割笔记(一): 使用YOLOv5-Seg对图像进行分割检测完整版(从自定义数据集到测试验证的完整流程)
PHP中的设计模式:单例模式的深入探索与实践在PHP的编程实践中,设计模式是解决常见软件设计问题的最佳实践。单例模式作为设计模式中的一种,确保一个类只有一个实例,并提供全局访问点,广泛应用于配置管理、日志记录和测试框架等场景。本文将深入探讨单例模式的原理、实现方式及其在PHP中的应用,帮助开发者更好地理解和运用这一设计模式。
在PHP开发中,单例模式通过确保类仅有一个实例并提供一个全局访问点,有效管理和访问共享资源。本文详细介绍了单例模式的概念、PHP实现方式及应用场景,并通过具体代码示例展示如何在PHP中实现单例模式以及如何在实际项目中正确使用它来优化代码结构和性能。
92 2
SpringBoot单元测试快速写法问题之创建 PorkInst 实例如何解决
SpringBoot单元测试快速写法问题之创建 PorkInst 实例如何解决
apifox实例应用-自动化测试用例for循环的使用
总结来说,通过在Apifox自动化测试用例中结合for循环的使用,我们可以有效地对接口进行批量测试,提升测试效率和覆盖率。同时,通过参数化测试数据的灵活应用,能够确保我们的接口在不同的输入条件下都能保持正确的行为。这种方法能够显著减少手动测试工作量,同时通过标准化的流程确保测试的一致性。
516 0
软件测试之【基于开源商城系统fecmall功能测试项目实例】
软件测试之【基于开源商城系统fecmall功能测试项目实例】
715 0
软件测试之【基于开源商城系统fecmall功能测试项目实例】
DataWorks操作报错合集之在使用 DataWorks 进行 MongoDB 同步时遇到了连通性测试失败,实例配置和 MongoDB 白名单配置均正确,且同 VPC 下 MySQL 可以成功连接并同步,但 MongoDB 却无法完成同样的操作如何解决
DataWorks是阿里云提供的一站式大数据开发与治理平台,支持数据集成、数据开发、数据服务、数据质量管理、数据安全管理等全流程数据处理。在使用DataWorks过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
170 1
【阿里云弹性计算】ECS实例性能测试报告:阿里云实例性能横向评测
【5月更文挑战第27天】阿里云ECS性能横向评测对比了经济型e系列、计算型c7a系列实例的CPU、内存、网络和存储性能。使用SPEC CPU 2017、Stream、iperf和fio工具进行测试。结果显示,计算型c7a系列在CPU和网络性能上突出,经济型e系列性价比高。所有实例内存性能良好,ESSD云盘提供出色存储性能。用户应根据业务需求选择合适实例。
243 0
python自动化测试实战 —— 自动化测试框架的实例
python自动化测试实战 —— 自动化测试框架的实例
191 0
|
11月前
|
java面向对象高级分层实例_测试类(main方法所在的类)
java面向对象高级分层实例_测试类(main方法所在的类)

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等