雷火电竞-中国电竞赛事及体育赛事平台

歡迎來(lái)到入門(mén)教程網(wǎng)!

C#教程

當(dāng)前位置:主頁(yè) > 軟件編程 > C#教程 >

WPF如何繪制光滑連續(xù)貝塞爾曲線(xiàn)示例代碼

來(lái)源:本站原創(chuàng)|時(shí)間:2020-01-10|欄目:C#教程|點(diǎn)擊:

1.需求

WPF本身沒(méi)有直接把點(diǎn)集合繪制成曲線(xiàn)的函數(shù)??梢酝ㄟ^(guò)貝塞爾曲線(xiàn)函數(shù)來(lái)繪制?! ?/p>

貝茲曲線(xiàn)由線(xiàn)段與節(jié)點(diǎn)組成,節(jié)點(diǎn)是可拖動(dòng)的支點(diǎn),線(xiàn)段像可伸縮的皮筋,我們?cè)诶L圖工具上看到的鋼筆工具就是來(lái)做這種矢量曲線(xiàn)的。當(dāng)然在一些比較成熟的位圖軟件中也有貝塞爾曲線(xiàn)工具,如PhotoShop等。

貝塞爾曲線(xiàn)類(lèi)是:BezierSegment,三次貝塞爾曲線(xiàn),通過(guò)兩個(gè)控制點(diǎn)來(lái)控制開(kāi)始和結(jié)束方向。

QuadraticBezierSegment,二次貝塞爾,通過(guò)一個(gè)控制點(diǎn)來(lái)控制彎曲方向。

本文使用的是三次。

 

圖片來(lái)源維基百科

2.思路

大值思路是根據(jù)當(dāng)前點(diǎn),前一個(gè)點(diǎn),后一個(gè)點(diǎn),再后一個(gè)點(diǎn)。共四個(gè)點(diǎn),來(lái)生成一條三次貝塞爾曲線(xiàn)。

曲線(xiàn)需要(開(kāi)始點(diǎn),結(jié)束點(diǎn),控制點(diǎn)1,控制點(diǎn)2),圖中標(biāo)識(shí)的兩個(gè)紅色點(diǎn)即是控制點(diǎn)。

代碼主要是計(jì)算兩個(gè)紅色的控制點(diǎn)。

先計(jì)算相鄰點(diǎn)的中點(diǎn)【橙色】。

再將中點(diǎn)的連線(xiàn)平移到相鄰的位置【藍(lán)色點(diǎn)】,取得虛線(xiàn),得到虛線(xiàn)的端點(diǎn)【紅色】。

紅色,即為控制點(diǎn)。

3.主要代碼

/// <summary>
 /// 獲得貝塞爾曲線(xiàn)
 /// </summary>
 /// <param name="currentPt">當(dāng)前點(diǎn)</param>
 /// <param name="lastPt">上一個(gè)點(diǎn)</param>
 /// <param name="nextPt1">下一個(gè)點(diǎn)1</param>
 /// <param name="nextPt2">下一個(gè)點(diǎn)2</param>
 /// <returns></returns>
 private BezierSegment GetBezierSegment(Point currentPt, Point lastPt, Point nextPt1, Point nextPt2)
 {
  //計(jì)算中點(diǎn)
  var lastC = GetCenterPoint(lastPt, currentPt);
  var nextC1 = GetCenterPoint(currentPt, nextPt1); //貝塞爾控制點(diǎn)
  var nextC2 = GetCenterPoint(nextPt1, nextPt2);
  //計(jì)算相鄰中點(diǎn)連線(xiàn)跟目的點(diǎn)的垂足
  //效果并不算太好,因?yàn)榭赡茳c(diǎn)在兩個(gè)線(xiàn)上或者線(xiàn)的延長(zhǎng)線(xiàn)上,計(jì)算會(huì)有誤差
  //所以就直接使用中點(diǎn)平移方法。
  //var C1 = GetFootPoint(lastC, nextC1, currentPt);
  //var C2 = GetFootPoint(nextC1, nextC2, nextPt1);
  //計(jì)算“相鄰中點(diǎn)”的中點(diǎn)
  var c1 = GetCenterPoint(lastC, nextC1);
  var c2 = GetCenterPoint(nextC1, nextC2);
  //計(jì)算【"中點(diǎn)"的中點(diǎn)】需要的點(diǎn)位移
  var controlPtOffset1 = currentPt - c1;
  var controlPtOffset2 = nextPt1 - c2;
  //移動(dòng)控制點(diǎn)
  var controlPt1 = nextC1 + controlPtOffset1;
  var controlPt2 = nextC1 + controlPtOffset2;
  //如果覺(jué)得曲線(xiàn)幅度太大,可以將控制點(diǎn)向當(dāng)前點(diǎn)靠近一定的系數(shù)。
  controlPt1 = controlPt1 + 0 * (currentPt - controlPt1);
  controlPt2 = controlPt2 + 0 * (nextPt1 - controlPt2);
  var bzs = new BezierSegment(controlPt1, controlPt2, nextPt1, true);
  return bzs;
 }

效果圖如下:

 

4.源碼下載

http://xiazai.jb51.net/201804/yuanma/WPF-BezierSegment(jb51.net).rar

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)我們的支持。

上一篇:C#圖片查看器實(shí)現(xiàn)方法

欄    目:C#教程

下一篇:C# Oracle批量插入數(shù)據(jù)進(jìn)度條的實(shí)現(xiàn)代碼

本文標(biāo)題:WPF如何繪制光滑連續(xù)貝塞爾曲線(xiàn)示例代碼

本文地址:http://www.jygsgssxh.com/a1/C_jiaocheng/5207.html

網(wǎng)頁(yè)制作CMS教程網(wǎng)絡(luò)編程軟件編程腳本語(yǔ)言數(shù)據(jù)庫(kù)服務(wù)器

如果侵犯了您的權(quán)利,請(qǐng)與我們聯(lián)系,我們將在24小時(shí)內(nèi)進(jìn)行處理、任何非本站因素導(dǎo)致的法律后果,本站均不負(fù)任何責(zé)任。

聯(lián)系QQ:835971066 | 郵箱:835971066#qq.com(#換成@)

Copyright © 2002-2020 腳本教程網(wǎng) 版權(quán)所有