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-求两个矩形相连的几何的更多相关文章

  1. 2018.12.24 Spring中的aop演示(也就是运用aop技术实现代理模式)

    Aop的最大意义是:在不改变原来代码的前提下,也不对源代码做任何协议接口要求.而实现了类似插件的方式,来修改源代码,给源代码插入新的执行代码. 1.spring中的aop演示 aop:面向方面编程.不 ...

  2. Win10 UWP开发系列:实现Master/Detail布局

    在开发XX新闻的过程中,UI部分使用了Master/Detail(大纲/细节)布局样式.Win10系统中的邮件App就是这种样式,左侧一个列表,右侧是详情页面.关于这种 样式的说明可参看MSDN文档: ...

  3. win10 uwp 列表模板选择器

    本文主要讲ListView等列表可以根据内容不同,使用不同模板的列表模板选择器,DataTemplateSelector. 如果在 UWP 需要定义某些列的显示和其他列不同,或者某些行的显示和其他行不 ...

  4. loli的测试-2018.12.9

    模拟赛-2018.12.9 这是NOIP之后第一次模拟赛...但是考的比较悲惨. 非常喜欢写考试总结,不知道为什么... T1:https://www.luogu.org/problemnew/sho ...

  5. Win10 UWP开发系列:使用VS2015 Update2+ionic开发第一个Cordova App

    安装VS2015 Update2的过程是非常曲折的.还好经过不懈的努力,终于折腾成功了. 如果开发Cordova项目的话,推荐大家用一下ionic这个框架,效果还不错.对于Cordova.PhoneG ...

  6. Win10 UWP开发实现Bing翻译

    微软在WP上的发展从原来的Win7到Win8,Win8.1,到现在的Win10 UWP,什么是UWP,UWP即Windows 10 中的Universal Windows Platform简称.即Wi ...

  7. Win10/UWP开发—使用Cortana语音与App后台Service交互

    上篇文章中我们介绍了使用Cortana调用前台App,不熟悉的移步到:Win10/UWP开发—使用Cortana语音指令与App的前台交互,这篇我们讲讲如何使用Cortana调用App的后台任务,相比 ...

  8. 【Win10 UWP】后台任务与动态磁贴

    动态磁贴(Live Tile)是WP系统的大亮点之一,一直以来受到广大用户的喜爱.这一讲主要研究如何在UWP应用里通过后台任务添加和使用动态磁贴功能. 从WP7到Win8,再到Win10 UWP,磁贴 ...

  9. 2015.12.21~2015.12.24真题回顾!-- HTML5学堂

    2015.12.21~2015.12.24真题回顾!-- HTML5学堂 山不在高,有仙则名!水不在深,有龙则灵!千里冰封,非一日之寒!IT之路,须厚积薄发!一日一小练,功成不是梦!小小技巧,尽在HT ...

随机推荐

  1. 跟我一起做一个vue的小项目(五)

    接下来我们要做的是热门推荐页面,我们写一个推荐组件 使用的方法也是前端data中的数据渲染到页面上面,这里对文字过长取省略号的方法不成功使用了一个小技巧 使用了min-width:0 我们来看完整的代 ...

  2. 删除n天前的文件或文件夹 bat批处理

    @echo off @echo deleting... FORFILES /p "D:\a" /D -1 /C "cmd /c echo deleting @file . ...

  3. 状态压缩中常用的位运算(DP)

    面对位运算,一直很无感...可能数学太差,脑洞太小. 1.首先是最基本的: 与&,或|,非~,异或^. 2.获取一个或者多个固定位的值: 假设 x = 1010(二进制),我们要取左数第二位的 ...

  4. 在centos 6.3系统下安装java、tomcat环境的方法与步骤(方法经过验证,可安装成功)

    一.安装java1. 下载java二进制安装包 wget --no-cookies --no-check-certificate --header "Cookie: gpw_e24=http ...

  5. 2019.8.14 NOIP模拟测试21 反思总结

    模拟测试20的还没改完先咕着 各种细节问题=错失190pts T1大约三分钟搞出了式子,迅速码完,T2写了一半的时候怕最后被卡评测滚去交了,然后右端点没有初始化为n…但是这样还有80pts,而我后来还 ...

  6. Apache配置虚拟主机,全部指向一个目录

    配置虚拟主机的时候,全部指向了一个目录,解决方法是在httpd.conf中添加: NameVirtualHost *:80

  7. 强强联合 阿里云 RDS for SQL Server 与 金蝶 K/3 WISE 产品实现兼容适配

    强强联合 阿里云 RDS for SQL Server 与 金蝶 K/3 WISE 产品实现兼容适配,原K/3 WISE用户通过简单配置就可以无缝搭配RDS SQL Server使用,不需再费时费力自 ...

  8. HTML之meta标签缓存控制

    <meta http-equiv="pragram" content="no-cache"> 禁止浏览器从本地缓存中调阅页面. 网页不保存在缓存中, ...

  9. CSS:命名规范心得分享

    一个好的命名习惯(当然这里指的并不仅仅是CSS命名).不仅可以提高开发效率,而且有益于后期修改和维护. 假设我们当前使用的命名方式都是约定成俗的,所有人都是这样写,那么你去到一个新团队,或者别人来接手 ...

  10. git解决冲突的最佳方法2

    1.冲突后和远程仓库的文件进行比对的时候,善于用上图所示的按钮,会提高效率 copy all-nonconflicting changes from right to left next differ ...