2018-12-24-win10-uwp-求两个矩形相连的几何
title | author | date | CreateTime | categories |
---|---|---|---|---|
win10 uwp 求两个矩形相连的几何
|
lindexi
|
2018-12-24 20:51:49 +0800
|
2018-12-17 08:55:34 +0800
|
Win10 UWP
|
在写笔迹的过程,我需要做橡皮的功能,橡皮是一个矩形在移动,因为移动的过程是不连续的,需要将多个矩形组合为连续的几何
大概的做法就是连接两个矩形作为一个六边形或者一个大的矩形的方法,这个方法最简单是求闭包的方法
本文采用的坐标是左上角是 (0,0) 点,从左向右坐标变大,从上到下坐标变大
但是对于矩形可以做到特殊算法,提高速度,方法就是取矩形的左上角进行判断,如果判断两个矩形中的一个矩形的左边小于另一个矩形的左边,同时这个矩形的上边小于另一个矩形的上边。
也就是两个矩形中,满足下面公式,其中 rect1 和 rect2 的值可以互换
rect1.Left <= rect2.Left && rect1.Top <= rect2.Top
此时就可以认为两个矩形按照从左上角到右下角的坐标
于是连接 rect1 的左上角点 rect1 的右上角点 rect2 的右上角点 rect2 的右下角点 rect2 的左下角点 rect1 的左下角点就可以连接处理这个六边形或矩形
另一个是两个矩形是按照从左下角到右上角的坐标,需要判断两个矩形的左下角。如果存在一个矩形的左下角的左边比另一个矩形的左边小,同时这个矩形的下边比另一个矩形的下边大
在两个矩形中,满足下面方法,其中 rect1 和 rect2 的值可以互换
rect1.Left <= rect2.Left && rect1.Bottom >= rect2.Bottom
通过连接 rect1 的左上角 rect2 的左上角 rect2 的右上角 rect2 的右下角 rect1 的右下角 rect1 的左下角就可以连接处理这个六边形或矩形
下面是我写的一个呆磨,代码是通过 win2d 写的,需要通过 Nuget 安装 Win2d 然后在 xaml 设置 Grid 的 Name 为 Grid 在代码可以添加
var canvas = new CanvasAnimatedControl();
Grid.Children.Add(canvas); canvas.Draw += Canvas_Draw;
在鼠标移动的时候拿到坐标,作为第二个矩形的左上角
protected override void OnPointerMoved(PointerRoutedEventArgs e)
{
_move = e.GetCurrentPoint(Grid).Position;
base.OnPointerMoved(e);
} private Point _move;
然后在 Canvas_Draw
创建两个矩形
Rect rect1 = new Rect(50, 50, 10, 10);
Rect rect2 = new Rect(_move, new Size(10, 10));
可以看到矩形 1 是固定的,但是矩形2会安装鼠标的左上角作为矩形,所以可以通过鼠标看自己的方法是否符合
先将两个矩形画出来
ds.DrawRectangle(rect1, Colors.IndianRed);
ds.DrawRectangle(rect2, new Color()
{
R = 0x6f,
B = 0x5f,
G = 0x26,
A = 0xff
});
这里的 ds 就是通过 args.DrawingSession 创建
private void Canvas_Draw(ICanvasAnimatedControl sender, CanvasAnimatedDrawEventArgs args)
{
using (var ds = args.DrawingSession)
{ }
}
然后开始判断,两个矩形有两个不同的方法,按照不同对角线,这里直接开始写判断
if (rect1.Left <= rect2.Left && rect1.Top <= rect2.Top)
{
}
else if (rect2.Left < rect1.Left && rect2.Top < rect1.Top)
{
}
这就是第一个方法的判断,创建一个方法用于绘制,因为两个矩形的计算需要互换,通过创建方法的方法可以减少代码
private void VerpallWayhi(Rect rect1, Rect rect2, CanvasDrawingSession ds)
{
var canvasPathBuilder = new CanvasPathBuilder(ds.Device);
canvasPathBuilder.BeginFigure((float) rect1.Left, (float) rect1.Top);
canvasPathBuilder.AddLine((float) rect1.Right, (float) rect1.Top);
canvasPathBuilder.AddLine((float) rect2.Right, (float) rect2.Top);
canvasPathBuilder.AddLine((float) rect2.Right, (float) rect2.Bottom);
canvasPathBuilder.AddLine((float) rect2.Left, (float) rect2.Bottom);
canvasPathBuilder.AddLine((float) rect1.Left, (float) rect1.Bottom);
canvasPathBuilder.EndFigure(CanvasFigureLoop.Closed); var geometry = CanvasGeometry.CreatePath(canvasPathBuilder);
ds.DrawGeometry(geometry, new Color()
{
R = 0x56,
B = 0x56,
G = 0x56,
A = 0xff
}); canvasPathBuilder.Dispose();
geometry.Dispose();
}
请不要认为上面的代码很复杂,自己画一下就知道上面的方法
在调用的时候,需要互换矩形
if (rect1.Left <= rect2.Left && rect1.Top <= rect2.Top)
{
VerpallWayhi(rect1, rect2, ds);
}
else if (rect2.Left < rect1.Left && rect2.Top < rect1.Top)
{
VerpallWayhi(rect2, rect1, ds);
}
因为两个矩形的相对关系只有两种,可以在下面判断
else if (rect1.Left <= rect2.Left && rect1.Bottom >= rect2.Bottom)
{
}
else if (rect2.Left < rect1.Left && rect2.Bottom > rect1.Bottom)
{
}
同时创建新的方法,对不同的矩形画出六边形或矩形
private void Stoutiheagea(Rect rect1, Rect rect2, CanvasDrawingSession ds)
{
var canvasPathBuilder = new CanvasPathBuilder(ds.Device);
canvasPathBuilder.BeginFigure((float) rect1.Left, (float) rect1.Top);
canvasPathBuilder.AddLine((float) rect2.Left, (float) rect2.Top);
canvasPathBuilder.AddLine((float) rect2.Right, (float) rect2.Top);
canvasPathBuilder.AddLine((float) rect2.Right, (float) rect2.Bottom);
canvasPathBuilder.AddLine((float) rect1.Right, (float) rect1.Bottom);
canvasPathBuilder.AddLine((float) rect1.Left, (float) rect1.Bottom);
canvasPathBuilder.EndFigure(CanvasFigureLoop.Closed); var geometry = CanvasGeometry.CreatePath(canvasPathBuilder);
ds.DrawGeometry(geometry, new Color()
{
R = 0x56,
B = 0x56,
G = 0x56,
A = 0xff
}); canvasPathBuilder.Dispose();
geometry.Dispose();
}
现在互换矩形
else if (rect1.Left <= rect2.Left && rect1.Bottom >= rect2.Bottom)
{
Stoutiheagea(rect1, rect2, ds);
}
else if (rect2.Left < rect1.Left && rect2.Bottom > rect1.Bottom)
{
Stoutiheagea(rect2, rect1, ds);
}
运行代码可以看到有一个矩形跟随鼠标,同时会连接两个矩形
用到的代码
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
var canvas = new CanvasAnimatedControl();
Grid.Children.Add(canvas); canvas.Draw += Canvas_Draw;
} protected override void OnPointerMoved(PointerRoutedEventArgs e)
{
_move = e.GetCurrentPoint(Grid).Position;
base.OnPointerMoved(e);
} private Point _move; private void Canvas_Draw(ICanvasAnimatedControl sender, CanvasAnimatedDrawEventArgs args)
{
var cl = DrawRectangle(sender); using (var ds = args.DrawingSession)
{
ds.DrawImage(cl, new Vector2(10, 10));
}
} private CanvasCommandList DrawRectangle(ICanvasResourceCreator sender)
{
Rect rect1 = new Rect(50, 50, 10, 10);
Rect rect2 = new Rect(_move, new Size(10, 10)); var cl = new CanvasCommandList(sender);
using (var ds = cl.CreateDrawingSession())
{
ds.DrawRectangle(rect1, Colors.IndianRed);
ds.DrawRectangle(rect2, new Color()
{
R = 0x6f,
B = 0x5f,
G = 0x26,
A = 0xff
}); if (rect1.Left <= rect2.Left && rect1.Top <= rect2.Top)
{
VerpallWayhi(rect1, rect2, ds);
}
else if (rect2.Left < rect1.Left && rect2.Top < rect1.Top)
{
VerpallWayhi(rect2, rect1, ds);
}
else if (rect1.Left <= rect2.Left && rect1.Bottom >= rect2.Bottom)
{
Stoutiheagea(rect1, rect2, ds);
}
else if (rect2.Left < rect1.Left && rect2.Bottom > rect1.Bottom)
{
Stoutiheagea(rect2, rect1, ds);
}
}
return cl;
} private void Stoutiheagea(Rect rect1, Rect rect2, CanvasDrawingSession ds)
{
var canvasPathBuilder = new CanvasPathBuilder(ds.Device);
canvasPathBuilder.BeginFigure((float) rect1.Left, (float) rect1.Top);
canvasPathBuilder.AddLine((float) rect2.Left, (float) rect2.Top);
canvasPathBuilder.AddLine((float) rect2.Right, (float) rect2.Top);
canvasPathBuilder.AddLine((float) rect2.Right, (float) rect2.Bottom);
canvasPathBuilder.AddLine((float) rect1.Right, (float) rect1.Bottom);
canvasPathBuilder.AddLine((float) rect1.Left, (float) rect1.Bottom);
canvasPathBuilder.EndFigure(CanvasFigureLoop.Closed); var geometry = CanvasGeometry.CreatePath(canvasPathBuilder);
ds.DrawGeometry(geometry, new Color()
{
R = 0x56,
B = 0x56,
G = 0x56,
A = 0xff
}); canvasPathBuilder.Dispose();
geometry.Dispose();
} private void VerpallWayhi(Rect rect1, Rect rect2, CanvasDrawingSession ds)
{
var canvasPathBuilder = new CanvasPathBuilder(ds.Device);
canvasPathBuilder.BeginFigure((float) rect1.Left, (float) rect1.Top);
canvasPathBuilder.AddLine((float) rect1.Right, (float) rect1.Top);
canvasPathBuilder.AddLine((float) rect2.Right, (float) rect2.Top);
canvasPathBuilder.AddLine((float) rect2.Right, (float) rect2.Bottom);
canvasPathBuilder.AddLine((float) rect2.Left, (float) rect2.Bottom);
canvasPathBuilder.AddLine((float) rect1.Left, (float) rect1.Bottom);
canvasPathBuilder.EndFigure(CanvasFigureLoop.Closed); var geometry = CanvasGeometry.CreatePath(canvasPathBuilder);
ds.DrawGeometry(geometry, new Color()
{
R = 0x56,
B = 0x56,
G = 0x56,
A = 0xff
}); canvasPathBuilder.Dispose();
geometry.Dispose();
}
}
<script type="text/javascript" async src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-MML-AM_CHTML">
</script>
<script type="text/x-mathjax-config">
MathJax.Hub.Config({tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}});
</script>
2018-12-24-win10-uwp-求两个矩形相连的几何的更多相关文章
- 2018.12.24 Spring中的aop演示(也就是运用aop技术实现代理模式)
Aop的最大意义是:在不改变原来代码的前提下,也不对源代码做任何协议接口要求.而实现了类似插件的方式,来修改源代码,给源代码插入新的执行代码. 1.spring中的aop演示 aop:面向方面编程.不 ...
- Win10 UWP开发系列:实现Master/Detail布局
在开发XX新闻的过程中,UI部分使用了Master/Detail(大纲/细节)布局样式.Win10系统中的邮件App就是这种样式,左侧一个列表,右侧是详情页面.关于这种 样式的说明可参看MSDN文档: ...
- win10 uwp 列表模板选择器
本文主要讲ListView等列表可以根据内容不同,使用不同模板的列表模板选择器,DataTemplateSelector. 如果在 UWP 需要定义某些列的显示和其他列不同,或者某些行的显示和其他行不 ...
- loli的测试-2018.12.9
模拟赛-2018.12.9 这是NOIP之后第一次模拟赛...但是考的比较悲惨. 非常喜欢写考试总结,不知道为什么... T1:https://www.luogu.org/problemnew/sho ...
- Win10 UWP开发系列:使用VS2015 Update2+ionic开发第一个Cordova App
安装VS2015 Update2的过程是非常曲折的.还好经过不懈的努力,终于折腾成功了. 如果开发Cordova项目的话,推荐大家用一下ionic这个框架,效果还不错.对于Cordova.PhoneG ...
- Win10 UWP开发实现Bing翻译
微软在WP上的发展从原来的Win7到Win8,Win8.1,到现在的Win10 UWP,什么是UWP,UWP即Windows 10 中的Universal Windows Platform简称.即Wi ...
- Win10/UWP开发—使用Cortana语音与App后台Service交互
上篇文章中我们介绍了使用Cortana调用前台App,不熟悉的移步到:Win10/UWP开发—使用Cortana语音指令与App的前台交互,这篇我们讲讲如何使用Cortana调用App的后台任务,相比 ...
- 【Win10 UWP】后台任务与动态磁贴
动态磁贴(Live Tile)是WP系统的大亮点之一,一直以来受到广大用户的喜爱.这一讲主要研究如何在UWP应用里通过后台任务添加和使用动态磁贴功能. 从WP7到Win8,再到Win10 UWP,磁贴 ...
- 2015.12.21~2015.12.24真题回顾!-- HTML5学堂
2015.12.21~2015.12.24真题回顾!-- HTML5学堂 山不在高,有仙则名!水不在深,有龙则灵!千里冰封,非一日之寒!IT之路,须厚积薄发!一日一小练,功成不是梦!小小技巧,尽在HT ...
随机推荐
- 一些hbase的shell查询语句
华为bids(不想吐槽)种种原因只能用hbase shell查询,在此记录下自己探索的hbase shell 免得下次要用还得去找 scan 'ogg_sel_ioc_sv_product_name_ ...
- 阿里面试题,为什么wait()方法要放在同步块中?
某天我在***的时候,突然有个小伙伴微信上说:“哥,阿里面试又又挂了,被问到为什么wait()方法要放在同步块中,没答出来!” 我顿时觉得**一紧,仔细回顾一下,如果wait()方法不在同步块中,代码 ...
- LINUX设置SUID,SGID,Stick bit
前面介绍过SUID与SGID的功能,那么,如何打开文件使其成为具有SUID与SGID的权限呢?这就需要使用数字更改权限了.现在应该知道,使用数字 更改权限的方式为“3个数字”的组合,那么,如果在这3个 ...
- Leetcode475.Heaters供暖器
冬季已经来临. 你的任务是设计一个有固定加热半径的供暖器向所有房屋供暖. 现在,给出位于一条水平线上的房屋和供暖器的位置,找到可以覆盖所有房屋的最小加热半径. 所以,你的输入将会是房屋和供暖器的位置. ...
- Linux程序包管理初步-rpm的使用
在Linux系统上,一般而言,对于程序包管理器来说分为三类: debian:dpt,dpkg; (程序包后缀.deb) rhel:rpm (程序包后缀.rpm) suse:rp ...
- Centos Apache 多站点配置
首先明白APACHE配置文件位置 /etc/httpd/ 系统会自动加载 "/etc/httpd/conf.d" 目录下面的 "*.conf"文件 创建多个 & ...
- poj 3304 Segments(计算直线与线段之间的关系)
Segments Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10921 Accepted: 3422 Descrip ...
- python 显示彩色文本
实现过程: 终端的字符颜色是用转义序列控制的,是文本模式下的系统显示功能,和具体的语言无关. 转义序列是以ESC开头,即用\033来完成(ESC的ASCII码用十进制表示是27,用 ...
- 【大数据】Hadoop常用启动命令
Hadoop常用启停命令 最近在装大数据环境,不知由于年纪大的问题还是笨的缘故,老师记不住一些常用命令,在这里就单独记一下Hadoop常用的启停命令.Hadoop常用的启停命令都在hadoop/sbi ...
- springmvc java程序文件保存地址的路径问题
会保存为这种斜杠 不论之前填写的是什么样