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

简介: 原文:C# WPF动点任意移动气泡画法(解决方案使用到数学勾股定理、正弦定理、向量知识)。    许久没写博客了,最近在研究WPF下气泡的画法,研发过程还是比较艰辛的(主要是复习了高中的数学知识,MMP全忘光了),这篇博客主要是提供一个思路给大家参考,如果有大神还有更好的解决方案可以不吝您的言论尽情留言。
原文: 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之后的效果。个人思路仅供参考。(这是原创文章,如有转载,请备注清楚)

     

 

 

 

  

 

 

 

 

目录
相关文章
|
7月前
|
开发框架 前端开发 JavaScript
C# 6.0+JavaScript云LIS系统源码  云LIS实验室信息管理新型解决方案
云LIS是为区域医疗提供临床实验室信息服务的计算机应用程序,可协助区域内所有临床实验室相互协调并完成日常检验工作,对区域内的检验数据进行集中管理和共享,通过对质量控制的管理,最终实现区域内检验结果互认。其目标是以医疗服务机构为主体,以医疗资源和检验信息共享为目标,集成共性技术及医疗服务关键技术,建立区域协同检验,最大化利用有限的医疗卫生资源。
177 1
C# WPF 中 外部图标引入iconfont,无法正常显示问题 【小白记录】
本文介绍了在C# WPF应用程序中引入外部iconfont图标时可能遇到的显示问题及其解决方法:1) 检查资源路径和引入格式是否正确,确保字体文件引用格式为“#xxxx”,并正确指向字体文件位置;2) 确保图标资源被包含在程序集中,通过设置字体文件的生成操作为Resource(资源)来实现。
C# WPF 中 外部图标引入iconfont,无法正常显示问题 【小白记录】
|
3月前
|
编解码 C# 数据库
C# + WPF 音频播放器 界面优雅,体验良好
【9月更文挑战第18天】这是一个用 C# 和 WPF 实现的音频播放器示例,界面简洁美观,功能丰富。设计包括播放/暂停按钮、进度条、音量控制滑块、歌曲列表和专辑封面显示。功能实现涵盖音频播放、进度条控制、音量调节及歌曲列表管理。通过响应式设计、动画效果、快捷键支持和错误处理,提升用户体验。可根据需求扩展更多功能。
143 3
|
4月前
|
C#
C# WPF 将第三方DLL嵌入 exe
C# WPF 将第三方DLL嵌入 exe
99 0
|
4月前
|
前端开发 C# 容器
WPF/C#:实现导航功能
WPF/C#:实现导航功能
99 0
|
4月前
|
设计模式 测试技术 C#
WPF/C#:在WPF中如何实现依赖注入
WPF/C#:在WPF中如何实现依赖注入
86 0
|
4月前
|
前端开发 C# Windows
WPF/C#:如何实现拖拉元素
WPF/C#:如何实现拖拉元素
59 0
|
4月前
|
存储 C# 索引
WPF/C#:BusinessLayerValidation
WPF/C#:BusinessLayerValidation
37 0
|
4月前
|
C#
WPF/C#:数据绑定到方法
WPF/C#:数据绑定到方法
50 0
|
4月前
|
前端开发 测试技术 C#
WPF/C#:在DataGrid中显示选择框
WPF/C#:在DataGrid中显示选择框
71 0