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. python 当文件目录不存在时,如何自动创建

    import os if not os.path.exists('foldername'): os.mkdir('foldername')

  2. 矩阵快速幂求Fibonacci

    原理 我们取矩阵A 则 F1=F2=1;则可以轻易求出F(i) #define maxn 2 #define mo 1000000007 struct Matrix{ long long a[maxn ...

  3. 2018-2019年中国CDN市场发展报告:阿里云成为中国CDN市场的领军者

    近日,权威ICT市场咨询机构计世资讯(CCW Research)发布<2018-2019年中国CDN市场发展报告>,报告显示,当前,随着新型信息技术在中国不断应用,以及互联网化新业务的快速 ...

  4. URI、URL 和 URN的区别

        关于URI:URL类似于住址,它告诉你一种寻找目标的方式.    URL和URN都是URI的子集. URI规范:协议名称://域名.根域名/目录/文件名.后缀#sddf URI :Unifor ...

  5. [转载]C语言EOF是什么?

    原贴网址:http://www.kuqin.com/language/20111112/314745.html 收藏于此: 我学习C语言的时候,遇到的一个问题就是EOF. 它是end of file的 ...

  6. 直接在安装了redis的Linux机器上操作redis数据存储类型--对Sorted-Sets操作

    一.概述: Sorted-Sets和Sets类型极为相似,它们都是字符串的集合,都不允许重复的成员出现在一个Set中.它们之间的主要差别是Sorted-Sets中的每一个成员都会有一个分数(score ...

  7. jnhs-springmvc 请求组合不正确,比如请求路径出现两次

    初学springmvc 向后台传参数,结果发现,一直404 404后没有路径,说明 没有进入controller 仔细一看,请求路径不对,重复出现 页面是这样写的 页面是这样写的 原因是,请求链接和当 ...

  8. HTML:把两张图片并排(行)显示

    <table><tr><td><img src=pic1.jpg border=0></td><td><img src=p ...

  9. python基础--字符编码以及文件操作

    字符编码: 1.运行程序的三个核心硬件:cpu.内存.硬盘 任何一个程序要是想要运算,肯定是先从硬盘加载到当前的内存中,然后cpu根据指定的指令去执行操作 2.python解释器运行一个py文件的步骤 ...

  10. new 在C++ 中的用法

    我对C++一无所知 看参考手册 来看一下参考手册,总共有三种用法 下面是网站上给出的例子 // operator new example #include <iostream> // st ...