1. 程式人生 > >OpenGL 實現Interpolation插值演算法

OpenGL 實現Interpolation插值演算法

這是一個靜態插值演算法的效果,圖形學中插值演算法應用十分廣,如動畫,photoshop, autocAD等軟體畫曲線,還有shader中的漸變上色也是一個硬體支援的插值演算法。

Interpolation是很低層的演算法,在圖形學中可以說無處不在。

本程式通過設定兩個vector,然後就可以在這兩個vector之間插入點,得到不同的效果

如兩個vector不同長度可以得到:


如果長度相同,就可以得到一個扇形:


全部自家定義的函式實現的,主要程式碼:

一)計算兩個向量的夾角,返回夾角大小:

float calVecTheta(Vector2f vfir, Vector2f vsec)
{
	float r = sqrtf(vfir.x * vfir.x + vfir.y * vfir.y);
	Vector2f vfirNor;
	vfirNor.x = vfir.x / r;
	vfirNor.y = vfir.y / r;
	
	r = sqrtf(vsec.x * vsec.x + vsec.y * vsec.y);
	Vector2f vsecNor;
	vsecNor.x = vsec.x / r;
	vsecNor.y = vsec.y / r;

	float theta = acosf(vfirNor.x * vsecNor.x + vfirNor.y * vsecNor.y);
	return theta;
}

二) 實現插值公式
void interpolateTwoVectors(Vector2f &vout, Vector2f &vfir, Vector2f &vsec,
					  float theta, float t)
{
	float a = sinf((1.0f-t) * theta) / sinf(theta);
	float b = sinf(t * theta) / sinf(theta);

	vout.x = a * vfir.x + b * vsec.x;
	vout.y = a * vfir.y + b * vsec.y;
}

三)產生頂點緩衝:
void createGeoAndBuffer()
{
	Vector2f vers[SEGMENTS*2+2];
	Vector2f vfir(1.f, 0.f);
	Vector2f vsec(-1.f/sqrtf(2.0f), 1.f/sqrtf(2.0f));
	vers[1] = vfir, vers[3] = vsec;

	float theta = calVecTheta(vfir, vsec);
	for (int i = 4, d = 1; i < SEGMENTS*2+2; i += 2, d++)
	{
		interpolateTwoVectors(vers[i+1], vfir, vsec, theta, 
			float(d) / (float)SEGMENTS);
	}

	glGenBuffers(1, &VBO);//注意是1, &VBO
	glBindBuffer(GL_ARRAY_BUFFER, VBO);
	glBufferData(GL_ARRAY_BUFFER, sizeof(vers), vers, GL_STATIC_DRAW);
}

以上就是主要的演算法程式碼了。


插值演算法還可以實現很多有趣的效果,因為它乃是動畫的最底層演算法,如很多人玩的flash動畫,flash會自動產生連貫的幀,實現動畫效果,很神奇吧? 其實產生的動畫效果就是使用了這個插值演算法的。呵呵,在底層邏輯原理面前,能解開一切神祕面紗,Magic has been demistified。

有空會實現更多效果。

相關推薦

OpenGL 實現Interpolation演算法

這是一個靜態插值演算法的效果,圖形學中插值演算法應用十分廣,如動畫,photoshop, autocAD等軟體畫曲線,還有shader中的漸變上色也是一個硬體支援的插值演算法。 Interpolation是很低層的演算法,在圖形學中可以說無處不在。 本程式通過設定兩個vec

Python 實現牛頓演算法

  匯入標頭檔案 import matplotlib.pyplot as plt from pylab import mpl import numpy as np import pandas as pd import math %matplotlib inline 得到差商表函

OpenGL(ES) 線性演算法黑邊問題探源

新浪微博  --  討論新聞組  --  程式碼庫  --  豆瓣 第二次使用別人的引擎碰到用OpenGL線性過濾演算法放大圖片出現黑邊的問題了,而引擎的製作者竟然不知道怎麼解決,兩次碰到

影象演算法的原理及C++實現

簡介: 在影象的處理過程中,經常需要對影象進行尺寸變換、旋轉或者扭曲等操作,在進行這些操作之後,原影象的尺寸往往就發生了改變,為了保持變換後的影象不失真,就需要對影象進行插值。 常見的插值方法有最近鄰插值和雙線性插值。 最近鄰插值: 最近鄰插值是最簡單的一種插值方式,

最臨近和雙線性內演算法實現比較

影象縮放顧名思義,就是把原影象按照目標尺寸放大或者縮小,是影象處理的一種。自然,影象縮放的核心也就是怎麼樣根據已知影象計算目標影象的各點畫素值。最簡單的是最臨近插值演算法,這種演算法就是根據原影象和目標影象的尺寸,計算縮放的比例,然後根據縮放比例計算目標畫素所依據的原畫素,過

三次樣條演算法的C++實現

標頭檔案: /* * Copyright (c) 2008-2011 Zhang Ming (M. Zhang), [email protected] * * This program is free software; you can redistri

最近鄰演算法的c++實現(QT框架)

最近鄰插值演算法是用影象中已知的畫素點填充輸出影象,採用畫素複製和畫素抽樣,使原圖放大或者縮小若干倍。 假設原影象的寬度和高度分別為 和 ,縮放後的影象的寬度為 和 ,那麼寬度和高度的縮放比例分別為:

用線性演算法實現影象縮放

  為了方便理解,先考慮一維情況下的線性插值  對於一個數列c,我們假設c[a]到c[a+1]之間是線性變化的  那麼對於浮點數x(a<=x<a+1),c(x)=c[a+1]*(x-a)+c[a]*(1+a-x);  這個好理解吧? 把這種插值方式擴充套件到二維情況  對於一個二維陣列c,我們假

雙線性演算法詳解並用matlab實現

雙線性插值演算法 介紹 雙線性插值法又稱為二次線性插值法。在傳統的插值演算法中,它的插值效果比nearest插值法要好的多,但是速度上也必然會慢很多,比bicubic(二次立方法)效果要差, 但速度上要優於bicubic。 它主要思想就是利用某

C++實現三次樣條演算法

程式中函式說明: 用float f(int x1, int x2, int x3)來寫函式; 用void cal_m(int n)來解係數; 用void printout(int n)來確定次數。 三次樣條插值演算法(壓緊樣條)原始碼: //#incl

Python實現牛頓法(差商表)

插值 ima proc 保存 append ces fun shadow 計算 def func(x,y,X,infor=True): list2=[y[0]] # 差商表的對角線的第一個元素始終是y0 count=1 while(T

Bayer模型的顏色演算法

        影象採集的功能一般用CCD和CMOS感測器來實現。但是這兩種影象感測器在一個畫素上只能採集 RGB顏色的一個分量,為了獲得最佳的影象效果,需要3個影象感測器分別採集不同的顏色分量,但考慮 到產品的成本及設計複雜度,通常的數字成像裝置用一

java實現牛頓

本程式碼經過本人優化後可直接執行,感謝支援! import java.util.Scanner; public class Newton_interpolation { /*拷貝向量*/ private static void copy_ve

影象縮放——雙線性演算法

在數學上,雙線性插值是有兩個變數的插值函式的線性插值擴充套件,其核心思想是在兩個方向分別進行一次線性插值。如果選擇一個座標系統使得  的四個已知點座標分別為 (0, 0)、(0, 1)、(1, 0) 和 (1, 1),那麼插值公式就可以化簡為: 用矩陣運算來表示的話就

影象處理中兩種基本的演算法(最鄰近法和雙線性內法)

在影象的基本仿射變換中,經常會碰到經過旋轉、縮放後灰度值如何賦值的問題。因為變換之後,影象的座標位置有可能是小數,所以就需要插值演算法來確定到底將該畫素賦予哪個位置。 1、最鄰近插值法(Nearest Interpolation) 這是最簡單的一種插值方法,不需要計算。在待

MATLAB實現牛頓的源程式

function yi=Newton(x,y,xi) %Newton插值方法,給定一系列插值的點(x,y),得到在x=xi處的,牛頓插值多項的值yi n=length(x); m=length(y); if m~=n     error('x,y的長度不一樣,請重新輸入!');     return end

拉格朗日演算法(附c++原始碼)

C++程式實現Lagrange插值公式     Lagrange插值公式,是屬於數值分析方面的內容。此處我想用C++語言程式來實現n各插值節點插值公式的求解,並求出在某一個插值節點對應的函式值。   對於Lagrange插值演算法的基本思想,在這裡我只想略提兩點,一個是拉格朗

opencv 學習--- 雙線性演算法原理簡述

***好記性不如爛筆頭*** 轉自: https://www.cnblogs.com/yssongest/p/5303151.html 1,原理   在影象的仿射變換中,很多地方需要用到插值運算,常見的插值運算包括最鄰近插值,雙線性插值,雙三次插值,蘭索思插值等方法,Op

最臨近、雙線性、三次卷積演算法比較

 //原文:http://blog.csdn.net/google0802/article/details/8938849 【我只是想把最近鄰這個弄過來╮(╯-╰)╭ 】 插值演算法對於縮放比例較小的情況是完全可以接受的,令人信服的。一般的,縮小0.5倍以上或放大3.

雙線性演算法進行影象縮放及效能效果優化

一)轉自http://handspeaker.iteye.com/blog/1545126 最近在程式設計時用到了雙線性插值演算法,對影象進行縮放。網上有很多這方面的資料,介紹的也算明白。但是,這些文章只介紹了演算法,並沒有具體說怎麼實現以及怎麼實現最好,舉個例子,你可以按照網上文章的演算法自己寫一個雙線性