码迷,mamicode.com
首页 > 其他好文 > 详细

风火轮 –动画效果:擦除、形状、轮子、随机线条、翻转远近、缩放、旋转、弹跳效果

时间:2015-03-06 16:35:35      阅读:227      评论:0      收藏:0      [点我收藏+]

标签:opencv

今天再花了一个白天时间,把PPT动画的进入效果全部实现。

1.  头文件

 

 

class TCbwAnimationEffect_Erase : publicTCbwAnimationEffect { // 擦除

         virtualvoid __fastcall BuildMaskMat(cv::Mat& destMat, cv::Mat& srcMat,

                   TRectdisplayRect);

 

public:

         __fastcallTCbwAnimationEffect_Erase();

         staticTCbwAnimationEffect * Build();

};

 

class TCbwAnimationEffect_Shape : publicTCbwAnimationEffect { // 形状

         virtualvoid __fastcall BuildMaskMat(cv::Mat& destMat, cv::Mat& srcMat,

                   TRectdisplayRect);

 

public:

         __fastcallTCbwAnimationEffect_Shape();

         staticTCbwAnimationEffect * Build();

};

 

class TCbwAnimationEffect_Wheel : publicTCbwAnimationEffect { // 轮子

         virtualvoid __fastcall BuildMaskMat(cv::Mat& destMat, cv::Mat& srcMat,

                   TRectdisplayRect);

 

public:

         __fastcallTCbwAnimationEffect_Wheel();

         staticTCbwAnimationEffect * Build();

};

 

class TCbwAnimationEffect_RandomLine :public TCbwAnimationEffect { // 随机线

         virtualvoid __fastcall BuildMaskMat(cv::Mat& destMat, cv::Mat& srcMat,

                   TRectdisplayRect);

 

         BYTE* FOccurredLines;

 

public:

         __fastcallTCbwAnimationEffect_RandomLine();

         staticTCbwAnimationEffect * Build();

};

 

 

class TCbwAnimationEffect_RotateToNear :public TCbwAnimationEffect_SameMask

{ // 翻转式由远及近

         virtualvoid __fastcall BuildDisplayMat(cv::Mat& destMat, cv::Mat& srcMat,

                  TRect displayRect);

 

public:

         __fastcallTCbwAnimationEffect_RotateToNear();

         staticTCbwAnimationEffect * Build();

};

 

class TCbwAnimationEffect_Zoom : publicTCbwAnimationEffect_SameMask { // 缩放

         virtualvoid __fastcall BuildDisplayMat(cv::Mat& destMat, cv::Mat& srcMat,

                   TRectdisplayRect);

 

public:

         __fastcallTCbwAnimationEffect_Zoom();

         staticTCbwAnimationEffect * Build();

};

 

class TCbwAnimationEffect_Rotate : publicTCbwAnimationEffect_SameMask { // 旋转

         virtualvoid __fastcall BuildDisplayMat(cv::Mat& destMat, cv::Mat& srcMat,

                   TRectdisplayRect);

 

public:

         __fastcallTCbwAnimationEffect_Rotate();

         staticTCbwAnimationEffect * Build();

};

 

class TCbwAnimationEffect_Bounce : publicTCbwAnimationEffect { // 随机线

         virtualTRect __fastcall BuildDisplayRect(OBJECTMAT * m);

public:

         __fastcallTCbwAnimationEffect_Bounce();

         staticTCbwAnimationEffect * Build();

};

 

2.  实现

 

// ***************************** 擦除效果**************************************

__fastcall TCbwAnimationEffect_Erase::TCbwAnimationEffect_Erase()

         :TCbwAnimationEffect() {

         EffectType= cetErase;

}

 

TCbwAnimationEffect *TCbwAnimationEffect_Erase::Build() {

         returnnew TCbwAnimationEffect_Erase;

}

 

void __fastcallTCbwAnimationEffect_Erase::BuildMaskMat(cv::Mat& destMat,

         cv::Mat&srcMat, TRect displayRect) {

         inteffectOptionType = MyOptionType.Items[1].CurrentValue * 2;

         //为了共用CbwEffectDirection类型

         TRectwholeRect(0, 0, displayRect.right - displayRect.left,

                   displayRect.bottom- displayRect.top);

         TRectpartRect = wholeRect;

         boolvertFlag =

                   (cedFromBottom== effectOptionType || cedFromTop == effectOptionType);

         doubledelta = double(FCurrentIndex + 1) / FPeriodLength * (vertFlag ?

                   partRect.bottom: partRect.right);

         if(cedFromBottom == effectOptionType) // 自底部

                            partRect.top= partRect.bottom - delta;

         if(cedFromLeft == effectOptionType) // 自左侧

                            partRect.right= partRect.left + delta;

         if(cedFromTop == effectOptionType) // 自顶部

                            partRect.bottom= partRect.top + delta;

         if(cedFromRight == effectOptionType) // 自右侧

                            partRect.left= partRect.right - delta;

         BYTE* pSrc = srcMat.data;

         BYTE* pDst = destMat.data;

         for(int row = 0; row < destMat.rows; ++row)

                   for(int col = 0; col < destMat.cols; ++col) {

                            boolhasValueFlag = (*pSrc++ != 0);

                            if(!hasValueFlag)

                                     *pDst = 0;

                            inty = (row - partRect.top) * (partRect.bottom - row);

                            intx = (col - partRect.left) * (partRect.right - col);

                            boolinFlag = (y >= 0 && x >= 0);

                            *pDst++= (inFlag ? 255 : 0);

                   }

}

// ***************************** 擦除效果**************************************

 

// ***************************** 形状效果**************************************

__fastcallTCbwAnimationEffect_Shape::TCbwAnimationEffect_Shape()

         :TCbwAnimationEffect() {

         EffectType= cetShape;

}

 

TCbwAnimationEffect *TCbwAnimationEffect_Shape::Build() {

         returnnew TCbwAnimationEffect_Shape;

}

 

void __fastcallTCbwAnimationEffect_Shape::BuildMaskMat(cv::Mat& destMat,

         cv::Mat&srcMat, TRect displayRect) {

         intzoomType = MyOptionType.Items[1].CurrentValue; // 放大、缩小

         intshapeType = MyOptionType.Items[2].CurrentValue; // 类型

         TRectwholeRect(0, 0, displayRect.right - displayRect.left,

                   displayRect.bottom- displayRect.top);

         doublecx = wholeRect.right / 2.0, cy = wholeRect.bottom / 2.0;

         doubledeltaX = double(FCurrentIndex + 1) / FPeriodLength * cx;

         doubledeltaY = double(FCurrentIndex + 1) / FPeriodLength * cy;

         doublestartX = deltaX, startY = deltaY;

         doubleendX = wholeRect.right - deltaX, endY = wholeRect.bottom - deltaY;

 

         if(zoomType == csdZoomOut) {

                   startX= cx - deltaX;

                   startY= cy - deltaY;

                   endX= cx + deltaX;

                   endY= cy + deltaY;

         }

         BYTE* pSrc = srcMat.data;

         BYTE* pDst = destMat.data;

         for(int row = 0; row < destMat.rows; ++row)

                   for(int col = 0; col < destMat.cols; ++col) {

                            boolhasValueFlag = (*pSrc++ != 0);

                            if(!hasValueFlag)

                                     *pDst = 0;

                            boolinFlag = false;

                            doublea = (cx - startX) * 1.5, b = (cy - startY) * 1.5;

                            if(shapeType == cstCircle) { // 圆

                                     if(a > 0 && b > 0) {

                                               doublev = (row - cy) * (row - cy) / (b * b) +

                                                        (col- cx) * (col - cx) / (a * a);

                                               inFlag= (v <= 1);

                                     }

                            }

                            if(shapeType == cstRect) { // 方框

                                     inFlag=

                                               (fabs(cx- startX) >= fabs(cx - col) && fabs(cy - startY) >=

                                               fabs(cy- row));

                            }

                            if(shapeType == cstDiamond) { // 菱形

                                     if(a > 0 && b > 0) {

                                               if(zoomType == csdZoomOut) {

                                                        a*= 2;

                                                        b*= 2;

                                               }

                                               boollr1 = (col < (((-a) * (1 - (row - cy) / (b))) + cx));

                                               boollr2 = (col < (((-a) * (1 - (row - cy) / (-b))) + cx));

                                               boollr3 = (col < (((a) * (1 - (row - cy) / (-b))) + cx));

                                               boollr4 = (col < (((a) * (1 - (row - cy) / (b))) + cx));

                                               inFlag= (!lr1 && !lr2 && lr3 && lr4);

                                     }

                            }

                            if(shapeType == cstPlus) { // 加号

                                     inFlag=

                                               (fabs(cx- startX) > fabs(cx - col) || fabs(cy - startY) >

                                               fabs(cy- row));

                            }

                            *pDst++= (inFlag != (zoomType == csdZoomOut) ? 0 : 255);

                   }

}

// ***************************** 形状效果**************************************

 

// ***************************** 轮子效果**************************************

__fastcallTCbwAnimationEffect_Wheel::TCbwAnimationEffect_Wheel()

         :TCbwAnimationEffect() {

         EffectType= cetWheel;

}

 

TCbwAnimationEffect * TCbwAnimationEffect_Wheel::Build(){

         returnnew TCbwAnimationEffect_Wheel;

}

 

void __fastcallTCbwAnimationEffect_Wheel::BuildMaskMat(cv::Mat& destMat,

         cv::Mat&srcMat, TRect displayRect) {

         boolclockwiseFlag = (MyOptionType.Items[1].CurrentValue == 0); // 方向

         intpattern = MyOptionType.Items[2].CurrentValue + 1; // 轮辐图案

         if(pattern == 5)

                   pattern= 8;

         TRectwholeRect(0, 0, displayRect.right - displayRect.left,

                   displayRect.bottom- displayRect.top);

         doublecx = wholeRect.right / 2.0, cy = wholeRect.bottom / 2.0;

         TCbwFloatPointcenterPoint(cx, cy);

 

         doubleunitDegree = 360 / pattern;

         doubledeltaDegree = double(FCurrentIndex + 1) / FPeriodLength * unitDegree;

         BYTE* pSrc = srcMat.data;

         BYTE* pDst = destMat.data;

         for(int row = 0; row < destMat.rows; ++row)

                   for(int col = 0; col < destMat.cols; ++col) {

                            TCbwFloatPointp(col, row);

                            doubletheta = p.ThetaToPoint(centerPoint);

                            if(clockwiseFlag)

                                     theta= 360 - theta;

                            boolinFlag = false;

                            for(int i = 0; i < pattern; ++i) {

                                     if(theta >= unitDegree * i && (theta - unitDegree * i) <=

                                               deltaDegree)

                                               inFlag= true;

                            }

                            *pDst++= inFlag ? 255 : 0;

                   }

}

// ***************************** 轮子效果**************************************

 

// ***************************** 随机线效果**************************************

__fastcallTCbwAnimationEffect_RandomLine::TCbwAnimationEffect_RandomLine()

         :TCbwAnimationEffect() {

         EffectType= cetRandomLine;

         FOccurredLines= NULL;

}

 

TCbwAnimationEffect *TCbwAnimationEffect_RandomLine::Build() {

         returnnew TCbwAnimationEffect_RandomLine;

}

 

void __fastcallTCbwAnimationEffect_RandomLine::BuildMaskMat(cv::Mat& destMat,

         cv::Mat&srcMat, TRect displayRect) {

         boolhorzFlag = (MyOptionType.Items[1].CurrentValue == 0); // 方向

         TRectwholeRect(0, 0, displayRect.right - displayRect.left,

                   displayRect.bottom- displayRect.top);

         inttotalLineNumber = (horzFlag ? wholeRect.bottom : wholeRect.right);

         intnumber = double(FCurrentIndex + 1) / FPeriodLength * totalLineNumber;

         if(!FOccurredLines) {

                   FOccurredLines= new BYTE[totalLineNumber];

                   ZeroMemory(FOccurredLines,totalLineNumber);

         }

         intdestNumber =

                   number-int(double(FCurrentIndex) / FPeriodLength * totalLineNumber);

         BYTE* pSrc = srcMat.data;

         BYTE* pDst = destMat.data;

         vector<int>totalLines;

         for(int i = 0; i < totalLineNumber; ++i)

                   totalLines.push_back(i);

         while(destNumber-- > 0 && totalLines.size()) {

                   intn = random(totalLines.size());

                   while(FOccurredLines[totalLines[n]]) {

                            totalLines.erase(totalLines.begin()+ n);

                            n= random(totalLines.size());

                   }

                   FOccurredLines[totalLines[n]]= 1;

                   totalLines.erase(totalLines.begin()+ n);

         }

         for(int row = 0; row < destMat.rows; ++row)

                  for (int col = 0; col <destMat.cols; ++col) {

                            boolinFlag = (horzFlag ? FOccurredLines[row] :

                                     FOccurredLines[col]);

                            *pDst++= inFlag ? 255 : 0;

                   }

         if(FCurrentIndex == FPeriodLength - 1) {

                   deleteFOccurredLines;

                   FOccurredLines= NULL;

         }

}

// ***************************** 随机线效果**************************************

 

// ***************************** 翻转式由远及近效果**************************************

__fastcallTCbwAnimationEffect_RotateToNear::TCbwAnimationEffect_RotateToNear()

         :TCbwAnimationEffect_SameMask() {

         EffectType= cetRotateToNear;

}

 

TCbwAnimationEffect *TCbwAnimationEffect_RotateToNear::Build() {

         returnnew TCbwAnimationEffect_RotateToNear;

}

 

void __fastcallTCbwAnimationEffect_RotateToNear::BuildDisplayMat

         (cv::Mat&destMat, cv::Mat& srcMat, TRect displayRect) {

         boolclockwiseFlag = (MyOptionType.Items[1].CurrentValue == 0); // 顺时针

         cv::Point2fcenter = cv::Point2f(srcMat.cols / 2, srcMat.rows / 2); // 旋转中心

         doubleangle = -45 * (1-double(FCurrentIndex + 1) / FPeriodLength); // 旋转角度

         if(clockwiseFlag)

                   angle*= -1;

         doublescale = 0.5 * (1+double(FCurrentIndex + 1) / FPeriodLength); // 缩放尺度

         cv::MatrotateMat = cv::getRotationMatrix2D(center, angle, scale);

         cv::warpAffine(srcMat,destMat, rotateMat, srcMat.size());

}

 

// ***************************** 翻转式由远及近效果**************************************

 

// ***************************** 缩放效果**************************************

__fastcallTCbwAnimationEffect_Zoom::TCbwAnimationEffect_Zoom()

         :TCbwAnimationEffect_SameMask() {

         EffectType= cetZoomEffect;

}

 

TCbwAnimationEffect *TCbwAnimationEffect_Zoom::Build() {

         returnnew TCbwAnimationEffect_Zoom;

}

 

void __fastcallTCbwAnimationEffect_Zoom::BuildDisplayMat(cv::Mat& destMat,

         cv::Mat&srcMat, TRect displayRect) {

         boolclockwiseFlag = (MyOptionType.Items[1].CurrentValue == 0); // 顺时针

         cv::Point2fcenter = cv::Point2f(srcMat.cols / 2, srcMat.rows / 2); // 旋转中心

         doublescale = 0.5 * (1+double(FCurrentIndex + 1) / FPeriodLength); // 缩放尺度

         cv::MatrotateMat = cv::getRotationMatrix2D(center, 0, scale);

         cv::warpAffine(srcMat,destMat, rotateMat, srcMat.size());

}

 

// ***************************** 缩放效果**************************************

 

// ***************************** 旋转效果**************************************

__fastcallTCbwAnimationEffect_Rotate::TCbwAnimationEffect_Rotate()

         :TCbwAnimationEffect_SameMask() {

         EffectType= cetRotateEffect;

}

 

TCbwAnimationEffect *TCbwAnimationEffect_Rotate::Build() {

         returnnew TCbwAnimationEffect_Rotate;

}

 

void __fastcallTCbwAnimationEffect_Rotate::BuildDisplayMat(cv::Mat& destMat,

         cv::Mat&srcMat, TRect displayRect) {

         boolhorzFlag = (MyOptionType.Items[1].CurrentValue == 0); // 方向

         doubleperiodLength = FPeriodLength / 2.0;

         doublevalue = (FCurrentIndex + 1) / periodLength;

         intsegment = value;

         value-= int(value);

         doublescale = fabs(value - 0.5) * 2;

         intcols = srcMat.cols * scale, rows = srcMat.rows;

         if(!horzFlag) {

                   cols= srcMat.cols;

                   rows= srcMat.rows * scale;

         }

         if(cols == 0 || rows == 0)

                   return;

         cv::MatpartMat = destMat(cv::Rect((destMat.cols - cols) / 2,

                   (destMat.rows- rows) / 2, cols, rows));

         cv::Sizedsize = cv::Size(cols, rows);

         resize(srcMat,partMat, dsize);

         if(value > 0.5 != (segment % 2))

                   flip(partMat,partMat, horzFlag ? 1 : 0);

}

// ***************************** 旋转效果**************************************

 

// ***************************** 弹跳效果**************************************

__fastcallTCbwAnimationEffect_Bounce::TCbwAnimationEffect_Bounce()

         :TCbwAnimationEffect() {

         EffectType= cetBounce;

}

 

TCbwAnimationEffect *TCbwAnimationEffect_Bounce::Build() {

         returnnew TCbwAnimationEffect_Bounce;

}

 

TRect __fastcallTCbwAnimationEffect_Bounce::BuildDisplayRect(OBJECTMAT * m) {

         doublex = double(FCurrentIndex + 1) / FPeriodLength;

         doublev = sin((x - 1) * 3 * PI);

 

         doubley = fabs(200 * v / exp(0.3 * (x - 1)));

         y= m->LeftTopPosition.y - y;

         x= m->LeftTopPosition.x + (x - 1) * 500;

         TRectresult(x, y, x + m->Mat.cols, y + m->Mat.rows);

         returnresult;

}

 

// ***************************** 弹跳效果**************************************

 

3.  配置

技术分享

4.  图标

技术分享

实现完成后,发现弹跳的效果没有达到预期。

技术分享


解决问题,先完成,再完善。

 

本周按计划完成PPT动画效果框架设计与实现。年也过完了,下周把电子黑板的功能更上一层楼。



风火轮 –动画效果:擦除、形状、轮子、随机线条、翻转远近、缩放、旋转、弹跳效果

标签:opencv

原文地址:http://blog.csdn.net/arwen/article/details/44101193

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!