貝塞爾曲線,以及用滑鼠和貝塞爾曲線互動
by 野比喵
這段時間感覺很蛋疼。。雖然各種遊戲玩的很開心。。還是多少要學習一下唄。。
做了個小東西,貼出來得瑟下。。能力有限,就先這麼著了。
別試圖找我要任何程式碼之類的。。我只是個amateur,這種帖子認真你就輸了。。
別試圖接分。。那是不可能的。。
當你對生活不滿意,工作不滿意,妹妹不滿意。。。
如果不想付出金錢去改變,活該苦逼。
如果不想付出精力去改變,活該苦逼。
如果不想付出生命去改變,活該苦逼。
如果不能忍受別人的鄙視,親,請給別人一個不鄙視你的理由先。。
其實這篇沒什麼技術含量,類似Photoshop裡的“鋼筆”工具。。
(程式碼裡面的招數我經常用,可以在前面的帖子裡翻到。。
前半部分是理論,可以在數學書上翻。後半部分是實踐,其實很簡單。。
正文開始
貝塞爾曲線
貝塞爾曲線(The Bézier Curves),是一種在計算機圖形學中相當重要的引數曲線(2D,3D的稱為曲面)。貝塞爾曲線於1962年,由法國工程師皮埃爾·貝塞爾(Pierre Bézier)所發表,他運用貝塞爾曲線來為汽車的主體進行設計。
線性曲線
給定點P0、P1,線性貝塞爾曲線只是一條兩點之間的直線。這條線由下式給出:
當引數t變化時,其過程如下:
線性貝塞爾曲線函式中的t會經過由P0至P1的B(t)所描述的曲線。例如當t=0.25時,B(t)即一條由點P0至P1路徑的四分之一處。就像由0至1的連續t,B(t)描述一條由P0至P1的直線。
二次曲線
二次方貝塞爾曲線的路徑由給定點P0、P1、P2的函式B(t)追蹤:
為建構二次貝塞爾曲線,可以中介點Q0和Q1作為由0至1的t:
* 由P0至P1的連續點Q0,描述一條線性貝塞爾曲線。
* 由P1至P2的連續點Q1,描述一條線性貝塞爾曲線。
* 由Q0至Q1的連續點B(t),描述一條二次貝塞爾曲線。
二次曲線看起來就是這樣的:
三次曲線
為建構高階曲線,便需要相應更多的中介點。對於三次曲線,可由線性貝塞爾曲線描述的中介點Q0、Q1、Q2,和由二次曲線描述的點R0、R1所建構。
P0、P1、P2、P3四個點在平面或在三維空間中定義了三次方貝塞爾曲線。曲線起始於P0走向P1,並從P2的方向來到P3。一般不會經過P1或P2;這兩個點只是在那裡提供方向資訊。P0和P1之間的間距,決定了曲線在轉而趨進P3之前,走向P2方向的“長度有多長”。
曲線的引數形式為:
看起來就是這樣的:
高階曲線
更高階的貝塞爾曲線,可以用以下公式表示:
用表示由點P0、P1、…、Pn所決定的貝塞爾曲線。則有:
更多的關於貝塞爾曲線的內容,你可以去查閱各種數學書。加油,求知的騷年。
應用
在幾乎所有的高階影象軟體中,均使用到了三次貝塞爾曲線來實現“平滑曲線”繪製功能。例如Photoshop中的“鋼筆”,CoralDraw中的“貝塞爾工具”,Fireworks中的“畫筆”。
在程式設計中實現
計算機繪圖
要“畫”出貝塞爾曲線,一般需要進行較多的計算,然後繪製出來,類似這樣:
繪製的程式碼可以在各類計算機圖形學書籍中找到。
GDI+
幸運的是,GDI+已經封裝好了貝塞爾曲線的繪製程式碼,如果你想畫出貝塞爾曲線,只用呼叫Graphics.DrawBezier方法:
這是一個三次貝塞爾曲線,其中4個點分別為:起點,起點控制點,終點,終點控制點。繪製出來的效果如下:
與滑鼠的互動
怎麼實現Photoshop裡那樣可以調整的貝塞爾曲線呢?兩種方法:
* 輸入新引數生成曲線
* 用滑鼠互動調整曲線
很顯然第二種看起來會拉風很多,那麼就來試試看。
你想要獲得是這樣的效果:
這是一條三次貝塞爾曲線,圖中應該這樣解讀:
所以需要幾個需要解決的:
* 表示貝塞爾曲線的錨點和控制點
* 繪製曲線和控制點/控制柄
* 滑鼠互動
看起來不是很難的樣子,那麼就來化整為零,各個擊破吧。
錨點
對於三次貝塞爾曲線而言,有兩個錨點:起始點和結束點。每個錨點有兩個座標:本身座標和控制點座標。於是,可以用這樣的類來描述:
三次貝塞爾曲線
三次曲線前面已經說過原理了,那麼它的結構應該就是這樣的:
畫出來
為了簡單,就用一個最基本的渲染器來畫,程式碼如下:
畫出曲線和控制點及其手柄:
畫出來的效果就是這樣的:
滑鼠互動
和滑鼠實際上是這樣互動的:
* 按下滑鼠,如果落點在某個控制點上,就表示選中了該點,否則落空
* 移動滑鼠,如果選中了某個控制點,則調整控制點座標至新座標,否則忽略
* 放開滑鼠,取消任何選擇
看起來只需要處理MouseDown,MouseMove和MouseUp這三個事件就夠了,很容易嘛。
先弄一個全域性標記:
然後處理滑鼠事件:
MouseDown:
MouseMove:
MouseUp:
為了簡單,重新整理就這麼弄了:
更高效的重新整理應該只處理髒區。
效果
最後看起來就像這樣。
就這麼簡單。
擴充套件和優化
要實現Photoshop那種曲線效果,需要多個錨點連線起來。上面的方法在效率上也還有可以提高的地方。
怎麼辦?
轉自:http://bbs.csdn.net/topics/390358020
相關推薦
貝塞爾曲線,以及用滑鼠和貝塞爾曲線互動
by 野比喵這段時間感覺很蛋疼。。雖然各種遊戲玩的很開心。。還是多少要學習一下唄。。做了個小東西,貼出來得瑟下。。能力有限,就先這麼著了。別試圖找我要任何程式碼之類的。。我只是個amateur,這種帖子認真你就輸了。。別試圖接分。。那是不可能的。。 當你對生活不滿意,工作不
C++ 物件和例項的區別,以及用new和不用new建立類物件區別
起初剛學C++時,很不習慣用new,後來看老外的程式,發現幾乎都是使用new,想一想區別也不是太大,但是在大一點的專案設計中,有時候不使用new的確會帶來很多問題。當然這都是跟new的用法有關的。new建立類物件,使用完後需使用delete刪除,跟申請記憶體類似。所以,n
Python:通過執行100萬次列印來比較C和python的效能,以及用C和python結合來解決效能問題的方法
python作為動態語言,開發效率相當高,但如我們所知,動態語言的執行效率往往是比較低的,請看下面簡單的測試過程: 一、 C語言實現100萬次列印: 程式碼: #include<stdio.h> #include <time.h> int
機器學習--樸素貝葉斯分類,以及拉普拉斯校準
機器學習算法 我們 earch lov 單詞 標註 樸素貝葉斯分類 images 劃分 原文鏈接:http://chant00.com/2017/09/18/%E8%B4%9D%E5%8F%B6%E6%96%AF/
ROC 曲線,以及AUC計算方式
true 樣本數目 opera block specific har -m 情況 排序 ROC曲線: roc曲線:接收者操作特征(receiveroperating characteristic),roc曲線上每個點反映著對同一信號刺激的感受性。 ROC曲線的橫軸: 負正類
mysqldump用法,以及用mysqldump做完全+增量備份
mysqldump 完全備份利用mysqldump對MySQL的完全備份和增量備份 備份的目的:當數據是一種重要資產時,我們需要經常對其進行備份,以防止數據損壞時,能夠及時將它恢復到損壞時的狀態。 備份內容:數據、配置文件、二進制日誌、事務日誌備份分類: 備份類型: 熱備份、溫備份和
Linux下對MySQL/MariaDB數據庫的基本操作以及linux mysql添加用戶,刪除用戶,以及用戶權限的授予
信息 查看 let quit mar 普通用戶 表名 mys xxxx 文章引用地址:https://www.cnblogs.com/Glory-D/p/7518541.html、https://www.cnblogs.com/zhchoutai/p/6929103.htm
java 強弱軟虛 四種引用,以及用到的場景
優先 時間 重新 通過 如果 sof queue hashcode 等待 1、利用軟引用和弱引用解決OOM問題:用一個HashMap來保存圖片的路徑和相應圖片對象關聯的軟引用之間的映射關系,在內存不足時,JVM會自動回收這些緩存圖片對象所占用的空間,從而有效地避免了OOM的
用cmd執行記事本寫的java檔案,以及jdk版本和執行版本不一致原因及其解決辦法
1.首先新建一個記事本,檔名改為Welcome.java拓展名也要改!(屬性裡面改為顯示拓展名,這樣才可以通過重新命名的方式改檔案個格式) public class Welcome{ public static void main(String[] args){ System.out.pr
Springboot 學習筆記 之 Day 5 如何加密,以及用Swagger2構建Restful API
先看一下使用Swagger2構建Restful API效果圖 超級簡單的,只需要在pom 中引用如下jar包 <dependency> <groupId>io.springfox</group
redis的主從複製和高可用、叢集,以及用redis做mysql快取
一、redis的安裝先在下載安裝包解壓後進入目錄應為已經有Makefile了所以直接make編譯這裡會報錯,需要gcc編譯器安裝好gcc,再次make編譯,還是會報錯;這個錯誤根據 Readme 可知需要執行 make MALLOC=libcmake完成後,提示去到 src
調取儲存過程的三個方法,以及用mybatis呼叫儲存過程
調取儲存過程的三個方法: 1.如果是PL/SQL命令視窗就用execute(簡寫:exec )儲存過程名,舉個例子: EXEC procedure;--procedure是儲存過程名 2.如果是PL/SQL視窗就用 begin 儲存過程名 end; begi
java 強弱軟虛 四種引用,以及用到的場景。
在JDK1.2後,java對引用的概念進行了擴充。按照引用強度依次從強到弱分為:強引用、軟引用(SoftReference)、弱引用(WeakReference)、虛引用(PhantomReference)用四種。 強引用:最常見的,不會被GC回收的物件,如 Object
自定義元素屬性,以及用jquery 去獲取當前點選的元素的這個自定義屬性
部分html: <button dataid="1" class="btn btn-primary btn-xs hanblog_edit">修改</button>juqery
SQL Convert的用法及獲取時間,以及用substring獲取相應的日期,小時,分鐘
語法 CONVERT ( data type, expression , [format-style ] ) 引數 data type 表示式將轉換成的資料型別。 expression 要轉換的表示式。 format-style 對於將字串轉換為日期
linux中mysql和mycat搭建,以及用mycat實現資料庫叢集
如果已安裝,則需要刪除已安裝的資料庫,使用以下命令來刪除資料庫 刪除命令:rpm -e --nodeps 包名 ( rpm -ev mysql-4.1.12-3.RHEL4.1 ) 刪除老版本mysql的開發標頭檔案和庫 命令:rm -fr /usr/lib/mysql rm -fr /usr/includ
關於struts2的namespace屬性,在位址列裡直接訪問action的方法 ,以及用一個jsp的表單跳到上面去
這裡的form表單中的action這樣填寫action="/aaa/hello/login" 其中的aaa是部署在Tomcat上的path裡的值一致,可以說是邏輯對映:如下圖所示 **********************************
單引號內引入變數 shell 命令輸出賦值給變數,以及用變數替換命令
單引號內巢狀單引號即可使用變數。 #!/bin/bash i=10 echo $i echo '$i'echo '$i is : '$i'' 執行結果 # ./test.sh 10 $i $i is : 10 單引號內巢狀單引號即可使用變數。 將命令賦值給變數,和將命令
springboot 實現攔截器許可權過濾,以及用攔截器實現操作日誌功能(二)
接上文 繼承WebMvcConfigurerAdapter 類,新增 上文寫的攔截類 具體程式碼如下: package com.hcmony.web.interceptor; import org
遺傳程式設計(GA,genetic programming)演算法初探,以及用遺傳程式設計自動生成符合題解的正則表示式的實踐
1. 遺傳程式設計簡介 0x1:什麼是遺傳程式設計演算法,和傳統機器學習演算法有什麼區別 傳統上,我們接觸的機器學習演算法,都是被設計為解決某一個某一類問題的確定性演算法。對於這些機器學習演算法來說,唯一的靈活性體現在引數搜尋空間上,向演算法輸入樣本,演算法藉助不同的優化手段,對引數進行調整,以此來得到一