WPF使用Canvas绘制可变矩形

WPF使用Canvas绘制可变矩形
原文:WPF使用Canvas绘制可变矩形

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/WANGYAN9110/article/details/38130661

1、问题以及解决办法

最近因为项目需要,需要实现一个位置校对的功能,大致的需求如下:有一个图片,有一些位置信息,但是位置信息可能和实际有些偏差,需要做简单调整,后面会对这张图片进行切割等,做些处理。(位置信息连接起来是一个个小矩形。)

解决以上问题的大致思路如下:使用canvas进行绘制,把图片作为canvas的背景,在canvas上绘制矩形,类似于qq截图一样,矩形框可以使用鼠标拖动调整大小。然后在记下修改后的位置,提供给后面切割图片使用。目前的关键问题就是实现类似qq截图那样可以拖动的矩形

2、实现的效果预览


以上是实现的demo的效果。主要由定位点和连线组成。

3、可变矩形实现

  1. 定位点
    定位点主要用于描述在矩形上的小方框,鼠标拖动的事件就是由它触发,它位置的移动会联动相关线的移动。


定位点主要是定位点的一些基本属性和基本方法,主要包括绘制方法,移动方法。
其中:AnchorPointType为定位点的类型;

    public enum AnchorPointType{/// <summary>/// 上下/// </summary>NS,/// <summary>/// 左右/// </summary>WE,/// <summary>/// 右上/// </summary>NE,/// <summary>/// 左下/// </summary>SW,/// <summary>/// 右下/// </summary>NW,/// <summary>/// 左上/// </summary>SE}

draw()方法用于绘制矩形:

        public Rectangle Draw() {double offset = this.Width / 2;Rectangle retc = new Rectangle(){Margin = new Thickness(this.X - offset, this.Y - offset, 0, 0),Width = this.Width,Height = this.Height,Fill = Brushes.LightGoldenrodYellow,Stroke = Brushes.Black,StrokeThickness = 1,DataContext = this.Key};this.retc = retc;return retc;}

move()方法用户改变定位点位置

        public void Move(double x,double y){double offset = this.Width / 2;this.retc.Margin = new Thickness(x-offset,y-offset,0,0);this.X = x;this.Y = y;}
  1. 可变矩形
    这部分主要实现绘制矩形功能,主要代码如下:
        public void Init(){//按x轴分类IEnumerable<IGrouping<double, Point>> pointXs = points.GroupBy(o => o.X);//按y周分类IEnumerable<IGrouping<double, Point>> pointYs = points.GroupBy(o => o.Y);//绘制竖线DrawXLine(pointXs);//绘制横线DrawYLine(pointYs);//设置定位点AddAnchorPoints();//绘制定位点并且添加事件foreach (AnchorPoint anchorPoint in anchorPoints){Rectangle rec=anchorPoint.Draw();rec.MouseLeftButtonDown += new MouseButtonEventHandler(rec_MouseLeftButtonDown);rec.MouseMove += new MouseEventHandler(rec_MouseMove);canvas.Children.Add(rec);}//canvas添加事件canvas.MouseLeftButtonUp += new MouseButtonEventHandler(canvas_MouseLeftButtonUp);canvas.MouseMove += new MouseEventHandler(canvas_MouseMove);canvas.MouseLeave += new MouseEventHandler(canvas_MouseLeave);}
    
    如上代码:
    如上代码:
    1、按x轴,y轴分类
    2、绘制竖线,横线
    3、设置定位点
    4、绘制定位点并且添加事件监听
    5、给canvas添加事件
    给每个定位点添加鼠标MouseMove和MouseLeftButtonDown事件,给canvas添加MouseMove,MouseLeave,MouseLeftButtonUp事件。
    具体代码不在粘贴了,如果需要代码,可以去下载源代码
  2. 矩形线联动
    矩形线联动,主要是以点带线,通过判断线是否和动点相关联,联动相关的线。主要代码如下:
         private void MoveLines(double x, double y){List<Line> moveLines = new List<Line>();moveLines = lines.Where(o => o.Y1 == curAnchorPoint.Y|| o.Y2 == curAnchorPoint.Y|| o.X1 == curAnchorPoint.X|| o.X2 == curAnchorPoint.X).ToList();foreach (Line line in moveLines){if (line.Y1 == curAnchorPoint.Y){line.Y1 = y;}if (line.Y2 == curAnchorPoint.Y){line.Y2 = y;}if (line.X1 == curAnchorPoint.X){line.X1 = x;}if (line.X2 == curAnchorPoint.X){line.X2 = x;}}}
    
  3. 定位点联动

点的联动,和线的联动方法类似,但是点的联动要比线的联动复杂,主要在以下三个方面:1、点的移动需要联动中点的联动。2、在矩形的四个顶点变动时,需要联动其他两个相邻的顶点,和相邻两条线的中点的联动。3、不同的方向点的联动,不一样,会有很多if else。
由于代码较长,就不粘贴了,需要源代码可以去获取源代码。
线中点联动:线的中点联动需要考虑,移动的点是否关联到计算这个中点的两个点或者一个点,关联到中点的这两个点如果有改变,则这个中点就需要改变。主要代码如下:

        private void MoveRefAnchorPoint(double x, double y,AnchorPoint movedAnchorPoint){foreach (AnchorPoint anchorPoint in anchorPoints){if (anchorPoint.RefPoint.Length == 2){if (anchorPoint.RefPoint[0].X == x && anchorPoint.RefPoint[0].Y == y){anchorPoint.RefPoint[0].X = movedAnchorPoint.X;anchorPoint.RefPoint[0].Y = movedAnchorPoint.Y;}else if (anchorPoint.RefPoint[1].X == x && anchorPoint.RefPoint[1].Y == y){anchorPoint.RefPoint[1].X = movedAnchorPoint.X;anchorPoint.RefPoint[1].Y = movedAnchorPoint.Y;}anchorPoint.X = (anchorPoint.RefPoint[0].X + anchorPoint.RefPoint[1].X) / 2;anchorPoint.Y = (anchorPoint.RefPoint[0].Y + anchorPoint.RefPoint[1].Y) / 2;anchorPoint.Move();}}}

以上为单个关联点改变的情况的代码,两个关联点都变动的代码和这个类似。

4、获取源代码

由于文字表达能力有限,另外说清点和线的关系,特别是点和线的联动,确实有点困难,如果感兴趣的话,强烈建议下载代码进行调试阅读。
https://github.com/wangyan9110/ProjectDemos/tree/master/WPFCanvasDemo


posted on 2018-08-30 11:21 NET未来之路 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/lonelyxmas/p/9559072.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/485234.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java中关于自增自减

Java中关于自增和自减 关于自增和自减&#xff0c;一直困扰着我&#xff0c;总是学完了当时明白&#xff0c;过了没多长时间又忘了&#xff0c;学的也不牢固。经过老师这一次的讲解&#xff0c;总结的这篇博客&#xff0c;如有错误还请指正。 第一题&#xff1a; 加上括号好看…

《麻省理工科技评论》发布2021年“全球十大突破性技术”

全文共计8398字&#xff0c;预计阅读时间10分钟来源 | DeepTech深科技&#xff08;转载请注明来源&#xff09;编辑 | 蒲蒲正如比尔盖茨所说&#xff0c;看过这些突破性技术之后&#xff0c;你会觉得 “美好的未来&#xff0c;值得我们为之奋斗”。日前&#xff0c;《麻省理工科…

@Valid的坑

Valid 只能用来验证 RequestBody 标注的参数&#xff0c;并且要写在 RequestBody 之前 转载于:https://www.cnblogs.com/jichen/p/9561622.html

Java——String类的方法

Java——String类的方法 String str1 “abc” 与String str2 new String(“abc”)有什么区别&#xff1f; 字符串常量存储在字符串常量池&#xff0c;目的是共享字符串非常量对象存储在堆中 String的常用方法 常用方法1&#xff1a; int length()&#xff1a;返回字符串的…

OpenAI魔法模型DALL-E论文、代码公布!

来源&#xff1a;AI科技评论编译&#xff1a;AI科技评论OpenAI在1月5日公布DALL-E模型以来&#xff0c;人们都惊艳于模型的语言想象力是如此丰富和细致。如今&#xff0c;我们终于等到了论文的公布&#xff0c;从而得以了解DALL-E天马行空创造力背后的奥秘。值得一提的是&#…

Maven项目无法加载jdbc.properties

Maven项目无法加载jdbc.properties(java.sql.SQLException: The server time zone value ‘&#xfffd;й&#xfffd;&#xfffd;&#xfffd;׼ʱ&#xfffd;&#xfffd;’ is unrecog) 1.JdbcUtils.java package com.zxm.utils;import java.io.InputStream; import ja…

Hinton:我终于想明白大脑怎么工作了!神经学家花三十年,寻找反向传播的生物机制...

来源&#xff1a;智源社区作者&#xff1a;Anil Ananthaswamy编译&#xff1a;梦佳「有一天晚上&#xff0c;我回家吃饭&#xff0c;激动地说『我终于想明白大脑是怎么工作的了&#xff01;』我15岁的女儿对我说&#xff0c;怎么又来了&#xff0c;老爸。」 …

Mybatis学习笔记(一)——项目搭建、导入依赖、相关配置

Mybatis学习笔记&#xff08;一&#xff09;——项目搭建、导入依赖、相关配置 传送门&#xff1a;Mybatis中文网&#xff08;入门手册&#xff09;Mybatis中文网 一、新建项目 在项目中新建模块&#xff1a; 二、学习Mybatis常用的依赖&#xff1a; <dependencies…

数学与工业革命

来源&#xff1a;中科院数学与系统科学研究院作者&#xff1a;黄雷&#xff0c;中科院数学与系统科学研究院数学&#xff0c;无时无刻不散发着它独特的魅力。上到宇宙飞船遨游外太空&#xff0c;下至小商小贩行走菜市间&#xff0c;这门与每个人生活都息息相关的学科一直在默默…

AI回溯过去解决复杂任务 |《自然》论文

来源&#xff1a;Nature Portfolio根据《自然》本周发表的一项研究First return, then explore&#xff0c;一类增强学习算法在雅达利经典游戏中的得分超过了人类玩家和先进的人工智能系统&#xff0c;算法挑战的游戏包括《蒙特祖马的复仇》&#xff08;Montezuma’s Revenge&a…

python数据图形化—— matplotlib 基础应用

matplotlib是python中常用的数据图形化工具&#xff0c;用法跟matlab有点相似。调用简单&#xff0c;功能强大。在Windows下可以通过命令行 pip install matplotlib 来进行安装。 以下为一些基础使用的例子&#xff1a; 1、绘制直线 先通过numpy生成在直线 y 5 * x 5 上的一组…

Snipaste的安装及快捷键的设置

Snipaste的安装及快捷键的设置 关于Snipaste&#xff1a; Snipaste 是一个简单但强大的截图工具&#xff0c;也可以让你将截图贴回到屏幕上&#xff01;可以将剪贴板里的文字或者颜色信息转化为图片窗口&#xff0c;并且将它们进行缩放、旋转、翻转、设为半透明&#xff0c;甚…

人与机器人的交互理论及其前景

来源&#xff1a;人机认知与实验室摘要&#xff1a;移动机器人的人机交互正处于早期阶段。大部分与机器人相关的用户交互都被数控能力所限制&#xff0c;向用户提供的最普遍的界面是以自动化平台提供的视频和对机器人的一定程度上的路径指挥。对于半自动能力的移动机器人&#…

计算机组成原理——Cache与主存的地址映射

Cache–主存的地址映射 由主存地址映象到cache地址称为地址映射 cache的基本结构&#xff1a; Cache的工作过程&#xff1a; CPU发出一个地址&#xff0c;同时发给主存和cache的地址映射机构&#xff0c;CPU会从主存中取出字还是从cache中取出字&#xff0c;主存将块号送入主…

申工智能有没有作弊?

来源&#xff1a;北国骑士在2021年农心杯赛场&#xff0c;韩国天才棋手申真谞连胜五轮&#xff0c;帮助韩国队夺得了阔别很久的团队冠军奖杯。从一连串的棋局来看&#xff0c;不管是日本选手还是中国对手&#xff0c;在韩国棋手面前都“不堪一击”。以申真谞为例&#xff0c;几…

浮点数加减法运算(对阶、尾数求和、规格化、舍入、溢出判断)

浮点数的加减法运算 前言&#xff1a; 运算过程&#xff1a;对阶、尾数求和、规格化、舍入、溢出判断 浮点加减运算 在计算机中&#xff0c;加减法运算用补码实现。 算术运算的常识&#xff1a;两个浮点数如果要进行加减法运算&#xff0c;它们的阶或者指数必须相等。 一、…

JSP实现登陆页面(表单提交、连接数据库、实现页面跳转)

JSP实现登陆页面(表单提交、连接数据库、实现页面跳转) 1.数据库设计 2.主页面展示 3.代码展示&#xff1a; index.jsp <% page language"java" contentType"text/html; charsetUTF-8"pageEncoding"UTF-8"%> <!DOCTYPE html PUBLIC …

任正非在“GTS云与终端云合作与融合进展”汇报会上的讲话

任正非内部讲话音频版作者&#xff1a;任正非来源&#xff1a;蓝血研究&#xff08;lanxueyanjiu)2021年1月12日&#xff0c;任正非在“GTS云与终端云合作与融合进展”汇报会上发表讲话。任正非要求&#xff0c;要围绕着体验把端、管、云拉通&#xff0c;优化华为的GTS服务网络…

Hinton一作新论文:如何在神经网络中表示“部分-整体层次结构”?

来源 | AI科技评论作者 | Geoffrey Hinton编译 | 陈彩娴AI科技评论在 Twitter 上发现了一篇Hinton的新论文&#xff0c;作者只有Hinton本人&#xff0c;这篇论文没有介绍具体的算法&#xff0c;而是描绘了一个关于表示的宏观构想&#xff1a;如何在神经网络中表示部分-整体层次…

概率校准与Brier分数

1.再提逻辑回归 前面已经讲过了逻辑回归&#xff0c;这里不再细讲&#xff0c;只是简单的说一个函数&#xff0c;主要是方便大家更好的理解概率校准。 在逻辑回归中&#xff0c;用的最多的就是sigmod函数&#xff0c;这个函数的作用就是把无限大或者无限小的数据压缩到[0,1]之间…