雷达扫描图中当雷达指针转动扫描到某一个点上的时候,判断这个点的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运行效果:


在线演示

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

  1. Silverlight实用窍门系列:59.多个中心点联动多线的可拖动控件扩展为拓扑图

    在本系列的第17篇文章中"Silverlight实用窍门系列:17.中心点联动多线的可拖动控件(绘制工程图.拓扑图基础) ",制作了基本的中心联动图标.有园友对此图的扩展不是很清晰 ...

  2. Silverlight实用窍门系列:71.Silverlight的Style

    此文章实例基于Silverlight实用窍门系列:68.Silverlight的资源字典ResourceDictionary,如有数据源疑问请参考该文章. 在Silverlight中的Style相当于 ...

  3. Silverlight实用窍门大集合+Silverlight 5 最全新特性【目录索引】

    在最近的几个月内整理出了Silverlight的一些相关的比较实用的功能讲解文章,并且随着Silverlight 5 beta版本的发布整理出的新特性系列文章,在这里做一个总的概括和索引,以方便大家观 ...

  4. Silverlight实用窍门系列:40.Silverlight中捕捉视频,截图保存到本地

    在Silverlight中我们可以捕捉视频设备以制作视频会议系统,或者通过视频设备截图功能上传头像等功能. 下面我们通过一个简单的实例来访问视频设备,并且截取图像下载该截图文件至本地. 一.在Silv ...

  5. Silverlight实用窍门系列:40.Silverlight中捕捉视频,截图保存到本地【附带实例源码】...

    在Silverlight中我们可以捕捉视频设备以制作视频会议系统,或者通过视频设备截图功能上传头像等功能. 下面我们通过一个简单的实例来访问视频设备,并且截取图像下载该截图文件至本地. 一.在Silv ...

  6. Silverlight实用窍门系列:61.Silverlight中的Trigger触发器,自定义翻页触发器

    在Silverlight应用程序和客户进行交互工作的时候可以不用写后台代码而通过Xaml代码来实现,在本文我们将学习了解Trigger触发器. Trigger触发器:引发动作的因素,比如鼠标点击.键盘 ...

  7. Silverlight实用窍门系列:35.细解Silverlight冒泡路由事件和注册冒泡路由事件【附带实例源码】...

    Silverlight中的事件分为普通事件和冒泡路由事件,它并没有包括WPF中的隧道路由事件,在本章中将详细讲解冒泡路由事件和如何注册一个冒泡路由事件. 一.细解冒泡路由事件 冒泡路由事件可以比喻为: ...

  8. Silverlight实用窍门系列:22.Silverlight使用WebService调用C++,Delphi编写的DLL文件【实例源码下载】...

    在Silverlight程序(非Out of Browser模式)中是无法直接调用DLL的,但是很多的计算或者其他应用程序的调用中我们需要用到DLL的加载.比如调用DLL来识别身份证读卡器传输过来 ...

  9. Silverlight实用窍门系列:66.Silverlight的数据模板DataTemplate(二)获取数据模板控件...

    在Silverlight中我们使用了数据模板,在很多时候也需要获取到数据模板上的控件,并且进行改变.本文使用的实例数据源和上节相同,如需了解请下载源码查看. 当然在这里我们可以分为获取数据模板原始控件 ...

最新文章

  1. 详细解析Java中抽象类和接口的区别
  2. Python之实现一个简易计算器
  3. linux网络编程--阻塞与非阻塞
  4. configurations in Gateway hub system
  5. 你知道GNU C 对C语言的扩展吗?
  6. Makefile系列之五 :函数
  7. poj2914无向图的最小割
  8. 五子棋c语言代码光标,c语言写的鼠标操作的五子棋游戏,欢迎观赏!
  9. 密码库LibTomCrypt学习记录——(1.0)分组密码算法——概述
  10. 文件夹删不掉,显示有文件打开怎么办
  11. U盘格式化后容量变小问题修复方案
  12. Gungho重点工作事项督办督查跟踪管理方案
  13. 移动apn接入点哪个快_中国移动接入点设置哪个快
  14. 阿里云国际版云服务器防火墙设置
  15. PHP 核心技术与最佳实践
  16. Spring--官方文档部分翻译(第五章 面向Aspect的编程-AOP)
  17. Win11下载与安装
  18. 什么是超链接:下划线、样式、字体颜色、代码怎么做?
  19. 收银系统可以管理童装店衣服不同的尺码吗?
  20. 计算机辅助教学时必不可少的,浅谈计算机辅助教学在历史教学中的作用及应用.doc...

热门文章

  1. 广州移动MGV3001_ZG_S905L3_UWE5621DS_线刷固件包
  2. 【通刷】_晶晨S905L3A、S905L3AB芯片_安卓9.0_AI语音_完美线刷固件包
  3. python3 cookie_Python3标准库:http.cookies HTTP cookie
  4. 德国汉诺威地面材料展览会搭建就找上海宽创国际
  5. 测试用例设计—场景分析法
  6. JAVA线上故障排查招式
  7. web前端程序员到底值多少钱?
  8. 宝来客:结婚率创新低,黄金珠宝销售受影响
  9. 欢迎大家加入Xcode公社
  10. 标梵互动智建中健健身整合营销方案