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

许久没写博客了,最近在研究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进行顺逆时针进行旋转

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

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

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

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

1 //开始连线画点
2             PathFigure PointPathFigure = new PathFigure();
3             PointPathFigure.StartPoint = CurrentFixedPoint;
4             PointPathFigure.Segments.Add(new LineSegment(new Point(tmpPoint.X, tmpPoint.Y), true));
5             PointPathFigure.Segments.Add(new LineSegment(new Point(tmpPoint2.X, tmpPoint2.Y), true));
6
7             PathGeometry myPathGeometry = new PathGeometry();
8             myPathGeometry.Figures.Add(PointPathFigure);

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

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

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

时间: 2024-08-08 11:27:41

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

WPF与中文输入法兼容性问题的解决方案

问题 我在使用WPF进行编程的时候,发现的一个最大问题就是WPF与中文输入法的兼容性问题. 出现的问题大概分为两种: 程序崩溃: 无法切换输入法. 在笔者的环境中并未遇到过崩溃的情况,只是后一种情况.但我想这两种情况的原因应该一样. 具体的表现为:在WPF中的Textbox控件中输入汉字的时候,我们需要先切换输入法.切换之后状态栏显示切换成功,而开始键入拼音的时候却发现直接将拼音输入了Textbox框中,情形好似并未切换成功. 而且更为棘手的是,这种情况并不是绝对的,重启程序和多次切换输入法都可

【WPF学习】第三十三章 高级命令

前面两章介绍了命令的基本内容,可考虑一些更复杂的实现了.接下来介绍如何使用自己的命令,根据目标以不同方式处理相同的命令以及使用命令参数,还将讨论如何支持基本的撤销特性. 一.自定义命令 在5个命令类(ApplicationCommands.NavigationCommands.EditingCommands.ComponentCommands以及MediaCommands)中存储的命令,显然不会为应用程序提供所有可能需要的命令.幸运的是,可以很方便地自定义命令,需要做的全部工作就是实例化一个新的

WPF绘制矢量图形模糊的问题

WPF默认提供了抗锯齿功能,通过向外扩展的半透明边缘来实现模糊化.由于WPF采用了设备无关单位,当设备DPI大于系统DPI时,可能会产生像素自动扩展问题,这就导致线条自动向外扩展一个像素,并且与边缘相邻的线条颜色变成了半透明,如下图所示: 这种特性在绘制细线条的时候会导致一些我们所不期望的结果:颜色变淡,线条模糊,线条变粗.很多时候,我们是无法绘制一个像素的清晰的线条的.对于这个问题,WPF给我们提供了几种解决方案: 1.设置像素对齐 对于系统内置的一些控件,通过设置SnapsToDeviceP

iOS开发Facebook POP动效库使用教程

如果说Origami这款动效原型工具是Facebook Paper的幕后功臣,那么POP便是Origami的地基.感谢Facebook开源了POP动效库,让人人都能制作出华丽的动效.我们只需5步,便能搞定酷炫的动效. 步骤1: 安装 使用CocoaPods安装POP,只需要在Podfile中加入这么一行: pod 'pop', '~> 1.0' 或者如果想要手动添加,那么参考POP Github中的描述: 除此之外,你还可以将工程添加到工作区里面,然后采用提供的配制文件.或者手动复制POP子目录

WPF自定义控件第一 - 进度条控件

本文主要针对WPF新手,高手可以直接忽略,更希望高手们能给出一些更好的实现思路. 前期一个小任务需要实现一个类似含步骤进度条的控件.虽然对于XAML的了解还不是足够深入,还是摸索着做了一个.这篇文章介绍下实现这个控件的步骤,最后会放出代码.还请高手们给出更好的思路.同时也希望这里的思路能给同道中人一些帮助.话不多说,开始正题. 实现中的一些代码采用了网上现有的方案,代码中通过注释标记了来源,再次对代码作者一并表示感谢. 首先放一张最终效果图. 节点可以被点击 控件会根据绑定的集合数据生成一系列节

Facebook POP动效库使用教程

编者注:用Origami作iOS动效的同学如果愁怎么实现,可以把这个给开发看看作为参考哦 如果说Origami这款动效原型工具是Facebook Paper的幕后功臣,那么POP便是Origami的地基.感谢Facebook开源了POP动效库,让人人都能制作出华丽的动效.我们只需5步,便能搞定酷炫的动效. 步骤1: 安装 使用CocoaPods安装POP,只需要在Podfile中加入这么一行: pod 'pop', '~> 1.0' 或者如果想要手动添加,那么参考POP Github中的描述:

绕任意轴旋转的矩阵推导总结

前言 常用的几何变换中旋转是较为复杂的一种,最近看<Physically Based Rendering, Second Edition: From Theory To Implementation>一书涉及绕任意轴旋转的实现,也给出了大体思路,但具体的推导过程及最后的旋转矩阵并未直接地给出,故根据参考Animated CGEM: Rotation About an Arbitrary Axis总结(欢迎指正). (一)基础 1.点乘与叉乘 点乘(dot)亦称作内积或数量积,如图,a·b =

笔记03 MVVM 开发的几种模式(WPF)

转自http://www.cnblogs.com/buptzym/p/3220910.html 在WPF系(包括SL,WP或者Win8)应用开发中,MVVM是个老生常谈的问题.初学者可能不会有感觉,但当你写一个核心逻辑能在各种平台上无缝移植,而只需改改UI的时候,那种快感是无法用语言来形容的. 笔者当初接触时,对MVVM并不以为然,编了很多代码以后,反过来看MVVM for WPF的经典文章以后,才若有顿悟.标准的MVVM把程序分成了Model, ViewModel和 View三个部分,但方法是

#WPF的3D开发技术基础梳理

原文:#WPF的3D开发技术基础梳理 自学WPF已经有半年有余了,一遍用,一边学.但是一直没有去触摸WPF的3D开发相关技术,因为总觉得在内心是一座大山,觉得自己没有能力去逾越.最近因为一个项目的相关原因,需要用的3D技术,虽然内心没有底只能硬着头皮上了.最后效果还不错. 开发完之后,对WPF的开发小有所感,于是打算写下来,把相关知识梳理下.给正在学习WPF技术伙伴们一点帮助. 能力平平,知识有限,如有错误,还望雅正. 作为微软推广的一门软件开发技术,肯定会遵循一个基本准则:怎么方便怎么来,怎么