您的位置:首页 > 其它

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

2015-03-06 16:04 387 查看
今天再花了一个白天时间,把PPT动画的进入效果全部实现。

浮入效果

头文件

class TCbwAnimationEffect_Erase : public TCbwAnimationEffect { // 擦除

virtual void __fastcall BuildMaskMat(cv::Mat& destMat, cv::Mat& srcMat,

TRect displayRect);

public:

__fastcall TCbwAnimationEffect_Erase();

static TCbwAnimationEffect * Build();

};

class TCbwAnimationEffect_Shape : public TCbwAnimationEffect { // 形状

virtual void __fastcall BuildMaskMat(cv::Mat& destMat, cv::Mat& srcMat,

TRect displayRect);

public:

__fastcall TCbwAnimationEffect_Shape();

static TCbwAnimationEffect * Build();

};

class TCbwAnimationEffect_Wheel : public TCbwAnimationEffect { // 轮子

virtual void __fastcall BuildMaskMat(cv::Mat& destMat, cv::Mat& srcMat,

TRect displayRect);

public:

__fastcall TCbwAnimationEffect_Wheel();

static TCbwAnimationEffect * Build();

};

class TCbwAnimationEffect_RandomLine : public TCbwAnimationEffect { // 随机线

virtual void __fastcall BuildMaskMat(cv::Mat& destMat, cv::Mat& srcMat,

TRect displayRect);

BYTE * FOccurredLines;

public:

__fastcall TCbwAnimationEffect_RandomLine();

static TCbwAnimationEffect * Build();

};

class TCbwAnimationEffect_RotateToNear : public TCbwAnimationEffect_SameMask

{ // 翻转式由远及近

virtual void __fastcall BuildDisplayMat(cv::Mat& destMat, cv::Mat& srcMat,

TRect displayRect);

public:

__fastcall TCbwAnimationEffect_RotateToNear();

static TCbwAnimationEffect * Build();

};

class TCbwAnimationEffect_Zoom : public TCbwAnimationEffect_SameMask { // 缩放

virtual void __fastcall BuildDisplayMat(cv::Mat& destMat, cv::Mat& srcMat,

TRect displayRect);

public:

__fastcall TCbwAnimationEffect_Zoom();

static TCbwAnimationEffect * Build();

};

class TCbwAnimationEffect_Rotate : public TCbwAnimationEffect_SameMask { // 旋转

virtual void __fastcall BuildDisplayMat(cv::Mat& destMat, cv::Mat& srcMat,

TRect displayRect);

public:

__fastcall TCbwAnimationEffect_Rotate();

static TCbwAnimationEffect * Build();

};

class TCbwAnimationEffect_Bounce : public TCbwAnimationEffect { // 随机线

virtual TRect __fastcall BuildDisplayRect(OBJECTMAT * m);

public:

__fastcall TCbwAnimationEffect_Bounce();

static TCbwAnimationEffect * Build();

};

实现:

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

__fastcall TCbwAnimationEffect_Erase::TCbwAnimationEffect_Erase()

: TCbwAnimationEffect() {

EffectType = cetErase;

}

TCbwAnimationEffect * TCbwAnimationEffect_Erase::Build() {

return new TCbwAnimationEffect_Erase;

}

void __fastcall TCbwAnimationEffect_Erase::BuildMaskMat(cv::Mat& destMat,

cv::Mat& srcMat, TRect displayRect) {

int effectOptionType = MyOptionType.Items[1].CurrentValue * 2;

// 为了共用CbwEffectDirection类型

TRect wholeRect(0, 0, displayRect.right - displayRect.left,

displayRect.bottom - displayRect.top);

TRect partRect = wholeRect;

bool vertFlag =

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

double delta = 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) {

bool hasValueFlag = (*pSrc++ != 0);

if (!hasValueFlag)

* pDst = 0;

int y = (row - partRect.top) * (partRect.bottom - row);

int x = (col - partRect.left) * (partRect.right - col);

bool inFlag = (y >= 0 && x >= 0);

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

}

}

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

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

__fastcall TCbwAnimationEffect_Shape::TCbwAnimationEffect_Shape()

: TCbwAnimationEffect() {

EffectType = cetShape;

}

TCbwAnimationEffect * TCbwAnimationEffect_Shape::Build() {

return new TCbwAnimationEffect_Shape;

}

void __fastcall TCbwAnimationEffect_Shape::BuildMaskMat(cv::Mat& destMat,

cv::Mat& srcMat, TRect displayRect) {

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

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

TRect wholeRect(0, 0, displayRect.right - displayRect.left,

displayRect.bottom - displayRect.top);

double cx = wholeRect.right / 2.0, cy = wholeRect.bottom / 2.0;

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

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

double startX = deltaX, startY = deltaY;

double endX = 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) {

bool hasValueFlag = (*pSrc++ != 0);

if (!hasValueFlag)

* pDst = 0;

bool inFlag = false;

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

if (shapeType == cstCircle) { // 圆

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

double v = (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;

}

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

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

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

bool lr4 = (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);

}

}

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

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

__fastcall TCbwAnimationEffect_Wheel::TCbwAnimationEffect_Wheel()

: TCbwAnimationEffect() {

EffectType = cetWheel;

}

TCbwAnimationEffect * TCbwAnimationEffect_Wheel::Build() {

return new TCbwAnimationEffect_Wheel;

}

void __fastcall TCbwAnimationEffect_Wheel::BuildMaskMat(cv::Mat& destMat,

cv::Mat& srcMat, TRect displayRect) {

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

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

if (pattern == 5)

pattern = 8;

TRect wholeRect(0, 0, displayRect.right - displayRect.left,

displayRect.bottom - displayRect.top);

double cx = wholeRect.right / 2.0, cy = wholeRect.bottom / 2.0;

TCbwFloatPoint centerPoint(cx, cy);

double unitDegree = 360 / pattern;

double deltaDegree = 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) {

TCbwFloatPoint p(col, row);

double theta = p.ThetaToPoint(centerPoint);

if (clockwiseFlag)

theta = 360 - theta;

bool inFlag = false;

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

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

deltaDegree)

inFlag = true;

}

*pDst++ = inFlag ? 255 : 0;

}

}

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

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

__fastcall TCbwAnimationEffect_RandomLine::TCbwAnimationEffect_RandomLine()

: TCbwAnimationEffect() {

EffectType = cetRandomLine;

FOccurredLines = NULL;

}

TCbwAnimationEffect * TCbwAnimationEffect_RandomLine::Build() {

return new TCbwAnimationEffect_RandomLine;

}

void __fastcall TCbwAnimationEffect_RandomLine::BuildMaskMat(cv::Mat& destMat,

cv::Mat& srcMat, TRect displayRect) {

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

TRect wholeRect(0, 0, displayRect.right - displayRect.left,

displayRect.bottom - displayRect.top);

int totalLineNumber = (horzFlag ? wholeRect.bottom : wholeRect.right);

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

if (!FOccurredLines) {

FOccurredLines = new BYTE[totalLineNumber];

ZeroMemory(FOccurredLines, totalLineNumber);

}

int destNumber =

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()) {

int n = random(totalLines.size());

while (FOccurredLines[totalLines
]) {

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

n = random(totalLines.size());

}

FOccurredLines[totalLines
] = 1;

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

}

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

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

bool inFlag = (horzFlag ? FOccurredLines[row] :

FOccurredLines[col]);

*pDst++ = inFlag ? 255 : 0;

}

if (FCurrentIndex == FPeriodLength - 1) {

delete FOccurredLines;

FOccurredLines = NULL;

}

}

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

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

__fastcall TCbwAnimationEffect_RotateToNear::TCbwAnimationEffect_RotateToNear()

: TCbwAnimationEffect_SameMask() {

EffectType = cetRotateToNear;

}

TCbwAnimationEffect * TCbwAnimationEffect_RotateToNear::Build() {

return new TCbwAnimationEffect_RotateToNear;

}

void __fastcall TCbwAnimationEffect_RotateToNear::BuildDisplayMat

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

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

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

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

if (clockwiseFlag)

angle *= -1;

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

cv::Mat rotateMat = cv::getRotationMatrix2D(center, angle, scale);

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

}

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

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

__fastcall TCbwAnimationEffect_Zoom::TCbwAnimationEffect_Zoom()

: TCbwAnimationEffect_SameMask() {

EffectType = cetZoomEffect;

}

TCbwAnimationEffect * TCbwAnimationEffect_Zoom::Build() {

return new TCbwAnimationEffect_Zoom;

}

void __fastcall TCbwAnimationEffect_Zoom::BuildDisplayMat(cv::Mat& destMat,

cv::Mat& srcMat, TRect displayRect) {

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

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

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

cv::Mat rotateMat = cv::getRotationMatrix2D(center, 0, scale);

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

}

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

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

__fastcall TCbwAnimationEffect_Rotate::TCbwAnimationEffect_Rotate()

: TCbwAnimationEffect_SameMask() {

EffectType = cetRotateEffect;

}

TCbwAnimationEffect * TCbwAnimationEffect_Rotate::Build() {

return new TCbwAnimationEffect_Rotate;

}

void __fastcall TCbwAnimationEffect_Rotate::BuildDisplayMat(cv::Mat& destMat,

cv::Mat& srcMat, TRect displayRect) {

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

double periodLength = FPeriodLength / 2.0;

double value = (FCurrentIndex + 1) / periodLength;

int segment = value;

value -= int(value);

double scale = fabs(value - 0.5) * 2;

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

if (!horzFlag) {

cols = srcMat.cols;

rows = srcMat.rows * scale;

}

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

return;

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

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

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

resize(srcMat, partMat, dsize);

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

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

}

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

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

__fastcall TCbwAnimationEffect_Bounce::TCbwAnimationEffect_Bounce()

: TCbwAnimationEffect() {

EffectType = cetBounce;

}

TCbwAnimationEffect * TCbwAnimationEffect_Bounce::Build() {

return new TCbwAnimationEffect_Bounce;

}

TRect __fastcall TCbwAnimationEffect_Bounce::BuildDisplayRect(OBJECTMAT * m) {

double x = double(FCurrentIndex + 1) / FPeriodLength;

double v = sin((x - 1) * 3 * PI);

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

y = m->LeftTopPosition.y - y;

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

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

return result;

}

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

配置:



图标



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



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

本周按计划完成PPT动画效果框架设计与实现。年也过完了,下周把电子黑板的功能更上一层楼。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: