许久没写博客了,最近在研究WPF下跟画板结合的轻量级气泡的画法,研发过程还是比较艰辛的(主要是复习了高中的数学知识,MMP全忘光了),这篇博客主要是提供一个思路给大家参考,如果有大神还有更好的解决方案可以不吝您的言论尽情留言。拿个这个类型的功能项目,首先分析可以假设气泡是由:椭圆/矩形/圆(椭圆的特例)和三角形组成,OK首先分步骤介绍研发步骤:

第一:首先我的所有的图形都是基于矩阵画出来的,坐标轴起点是(0,0),假设一个拖拉点DynamicPoint (x,y),和一个固定点FixedPoint (m,n);由两点即可确定一个矩形大小,从里面画出内接图形和一个三角形;

1、新建矩形  var TriagleRect = new Rect(FixedPoint, DynamicPoint);

2、假设矩形之内存在一个等比例大小的圆,而圆是由圆心和半径组成的直线所划过的弧确定的,半径R,圆心CenterXY (p,q);相当于已知

3、可以移动的点P设为:CurrentFixedPoint(s,t); 这个点是由鼠标捕获的相当于已知;

4、由动点CurrentFixedPoint(s,t)向圆 M(圆心为CenterXY (p,q),半径R)作两条圆的切线,求出两切点F1(f1x,f1y)、F2(f2x,f2y)坐标值?

如下图(做的图比较难看,做辅助之用)

到这边肯定很多人觉得很熟悉,没错这是高中的数学题,这边在研究的过程中研究了两种解决方案,下面简单的介绍下:

方案1:

如图,由圆心点C向两切点做垂直线,然后根据三角函数做辅助线PQ,QC得出斜边PC长,由图中可以知道

double Sine = R / AB; //求出正弦值

∠F1PC= Math.Round((Math.Asin(Sine) / Math.PI) * 180, 2);//把正弦值换算成角度

利用向量和向量模进行计算二元一次方程可以得出F1,F2坐标.

方程1:PF1向量=PC向量+CF1向量  ,这里可以得出一个关于F1的二元一次方程;

方程2:PF1向量的模=(PC平方+CF1平方)开根号,这里可以得出一个关于F1的二元二次方程;

由这两个方程式可以解出F1的坐标值,同理也可以得出F2的坐标值;

方案2:

也是如图,方案1是稍微复杂了一点,比较不利于软件当中的应用,这边着重介绍第二种算出切点的可行性方案;

double MB = Math.Sqrt(Math.Pow(PC, 2) - Math.Pow(R, 2));//MB为切线的长度

double Sine = R / AB; //求出正弦值

∠F1PC= Math.Round((Math.Asin(Sine) / Math.PI) * 180, 2);//把正弦值换算成角度

接下来跟方案1不同的地方是:我要让圆心点按照角度∠F1PC进行顺逆时针进行旋转

  //把移动点作为圆心按照角度SineAngle旋转,有方向,顺逆时针
Vector vector = Point.Subtract(CenterXY, CurrentFixedPoint);
Matrix matrix = new Matrix();
matrix.RotateAt(SineAngle, CurrentFixedPoint.X, CurrentFixedPoint.Y);
//转换成单位向量1
var v = matrix.Transform(vector);
v.Normalize(); Matrix matrix2 = new Matrix();
matrix2.ScaleAt(_vector, _vector, CurrentFixedPoint.X, CurrentFixedPoint.Y);
var v2 = matrix2.Transform(v);
return v2;

经过上面旋转,然后缩放到单位1的向量假设为PF1' ,然后按比例放大到PF1的模长之后得出向量PF1,这样就可以得出F1点坐标,同理得出F2;具体转换如下:

  //根据获得的向量值求出切点的坐标值
var tmpPoint = Point.Add(P, SecondPoint);
var tmpPoint2 = Point.Add(P, ThirdPoint);

这样就实现了移动动点P,F1,F2也会跟着角度进行实时变化,但是夹角不变,OK,现在动态的两个点都已经确认出来了,接下来就可以通过C#提供的方法进行连线,这样就组成了一个三角形,这个三角形是由内圆心出发延伸至动点P的图形。

 //开始连线画点
PathFigure PointPathFigure = new PathFigure();
PointPathFigure.StartPoint = CurrentFixedPoint;
PointPathFigure.Segments.Add(new LineSegment(new Point(tmpPoint.X, tmpPoint.Y), true));
PointPathFigure.Segments.Add(new LineSegment(new Point(tmpPoint2.X, tmpPoint2.Y), true)); PathGeometry myPathGeometry = new PathGeometry();
myPathGeometry.Figures.Add(PointPathFigure);

第二:两个独立图形出来之后那就是组合图形了,C#组合图形提供了一个专门的方法:Geometry.Combine(Geometry geometry1, Geometry geometry2, GeometryCombineMode mode, Transform transform),不多说不懂得可以查阅资料; 备注:ellipse 是第一个形状,四个中心点分别位于矩阵的边上;

             //组合图形
var geometry = Geometry.Combine(myPathGeometry, ellipse, GeometryCombineMode.Union, null); this.DrawGeometry(streamGeometryContext, geometry);

效果图如下:下面是任意移动动点P之后的效果。个人思路仅供参考。(这是原创文章,如有转载,请备注清楚)

C# WPF动点任意移动气泡画法(解决方案使用到数学勾股定理、正弦定理、向量知识)。的更多相关文章

  1. WPF 精准大小的消息气泡生成

    在其他网站发布过,都是这里写的. 全部为Wpf方式,生成的气泡宽度高度较为精确. 适用任意字体以及字号,可设置图像字体.字号.行间距.字间距.阴影.气泡宽度等,在RichtextboxHelper.c ...

  2. WPF应用程序支持多国语言解决方案

    原文:WPF应用程序支持多国语言解决方案 促使程序赢得更多客户的最好.最经济的方法是使之支持多国语言,而不是将潜在的客户群限制为全球近70亿人口中的一小部分.本文介绍四种实现WPF应用程序支持多国语言 ...

  3. 优动漫PAINT-凌霄花画法

    再见小清新~这次教程教授的是凌霄花的画法!话说这个作者的花卉系列都很米粒啊~配色什么的,赞到没话说~ 教程是简单,呃.... 没有优动漫PAINT软件肿么办? 别着急,╭(╯^╰)╮ 小编给你送来了 ...

  4. 优动漫PAINT-紫藤花画法

    本教程分享一篇使用优动漫PAINT绘制一树梦幻的紫藤萝花教程,原文转载自优动漫官网. 小清新紫藤萝教程,就到这里啦!有兴趣的可以尝试画一画哦,软件下载:www.dongmansoft.com/xiaz ...

  5. 优动漫PAINT-牵牛花画法教程

    喇叭型对画者自身的塑形功力会有较高的要求,作者很靠谱的把他的塑形方式详细呈现了出来~ 对于这样的一个仿真效果的牵牛花完全可以使用优动漫PAINT完成,简单又快捷,软件下载:http://www.don ...

  6. 如何组织一个同时面向 UWP/WPF/.Net Core 控制台的 C# 项目解决方案

    希望写一个小型工具,给自己和需要的人.考虑到代码尽可能的复用,我准备采用 .Net Standard 来编写大多数核心代码,并基于 .Net Core 编写跨平台控制台入口,用 WPF 编写桌面端 U ...

  7. [原创]WPF应用MediaPlayer播放声音断续、不全解决方案

    1.检查扬声器和驱动程序. 测试方法:首先,应用Windows Media Player播放器播放,看是否有问题,如果有问题,基本断定是驱动程序问题.其次,点击扬声器,选择测试,查看扬声器是否好用,如 ...

  8. 【转】WPF的知识

    [-] 闲话WPF之二XAML概述 闲话WPF之五XAML中的类型转换 闲话WPF之十六WPF中的资源 2 闲话WPF之十九WPF中的传递事件 1 闲话WPF之二十WPF中的传递事件 2 闲话WPF之 ...

  9. WPF图形/文字特别效果之一:交叉效果探讨

    原文:WPF图形/文字特别效果之一:交叉效果探讨 为了说明问题,先看下图:图1  完全重叠的单一颜色文字它是2008几个字的叠加,并且颜色为单一的红色.如果不仔细分辨,你或许无法一下子看出是2008. ...

随机推荐

  1. OpenGL ES2.0光照

    一.简单光照原理 平行光(正常光) 光照效果=   环境颜色 + 漫反射颜色 + 镜面反射颜色 点光源 光照效果=   环境颜色 + (漫反射颜色 + 镜面反射颜色)× 衰减因子 聚光灯 光照效果= ...

  2. 容器平台选型的十大模式:Docker、DC/OS、K8S 谁与当先?

    作者:刘超   来自:网易云 基础服务 无论是在社区,还是在同客户交流的过程中,总会被问到到底什么时候该用 Docker?什么时候用虚拟机?如果使用容器,应该使用哪个容器平台? 显而易见,我不会直接给 ...

  3. ASP.NET Core 网站发布到Linux服务器(转)

    出处;ASP.NET Core 网站发布到Linux服务器 长期以来,使用.NET开发的应用只能运行在Windows平台上面,而目前国内蓬勃发展的互联网公司由于成本的考虑,大量使用免费的Linux平台 ...

  4. LINUX 笔记-命令执行顺序 && ,||

    && 格式:命令1 && 命令2 说明:命令1返回真(即返回0,成功被执行)后,命令2才能够被执行 例:/apps/bin目录将会被移到/apps/dev/bin目录下 ...

  5. ASP.NET MVC @Html.Label的问题

    在使用@Html.Lable()来显示Model的某一个字符串属性时,如果该字符串中包含".",那么就会在最终呈现时被截掉开头至"."位置的字符.什么原因尚不清 ...

  6. Linux系列教程(六)——Linux文件搜索命令

    前一篇博客我们讲解了Linux链接命令和权限管理命令, 通过 ln -s  链接名 表示创建软链接,不加-s表示创建硬链接:还有三个更改权限的命令,chmod命令可以更改文件或目录权限,chown命令 ...

  7. 学习笔记TF052:卷积网络,神经网络发展,AlexNet的TensorFlow实现

    卷积神经网络(convolutional neural network,CNN),权值共享(weight sharing)网络结构降低模型复杂度,减少权值数量,是语音分析.图像识别热点.无须人工特征提 ...

  8. myeclipse自动保存修改代码

    当你修改过代码后,myeclipse往往要你手动的保存代码才能运行这个修改后的代码,要是不保存就会一直运行修改前的代码.只要修改myeclipse中这两项,就可以让它编译运行修改后的代码: Windo ...

  9. G彩娱乐网一个程序员到一个销售高手的心路历程

    0.引言 我大学本科读的是理工科,后来毕业以后,我逐渐走上了程 序员的道路.每天面对电脑一行一行的敲代码,这被我们程序员们戏称为"搬砖头",因为我们所做的事跟民工搬砖头砌墙本质上是 ...

  10. ldap数据库--ldapsearch,ldapmodify

    简单介绍一下ldapsearch命令,在ldap搜索条目时很有用,只要适当调整filter就可以. 命令如下: ldapsearch -h hostname -p port -b baseDN -D ...