用OPENCV寫的Mandelbrot集分形圖形

直接貼代碼吧,很好看,色彩很絢麗。

#include <stdio.h>
#include <stdlib.h>
#include "highgui.h"
#include "cv.h"
#include "cxcore.h"
#include<math.h>
#define M 400
#define max_times 200
int flag=0;
double XMax=2.0;
double XMin=-2.0;
double YMax=2.0;
double YMin=-2.0;
IplImage* workImg;
IplImage* imgshow;
CvRect ROI_rect;
CvScalar sca;
int judge(double a,double b);
void on_mouse(int event, int x,int y,int flags,void* param);
int main()
{
    workImg=cvCreateImage (cvSize(M,M),8,3);
    imgshow=cvCreateImage (cvSize(M,M),8,3);
    cvNamedWindow ("Opencv", 1);//能否拉伸
    cvMoveWindow("Opencv",0,0);//窗口在桌面的位置
    draw(M/2,M/2);
    printf("操作說明:\n1、左鍵放大\n2、滾輪平移\n3、右鍵恢復");
    cvNamedWindow("Opencv",CV_WINDOW_AUTOSIZE);
    cvSetMouseCallback("Opencv",on_mouse,NULL);
    cvWaitKey(0);
    cvDestroyWindow("Opencv");
    cvReleaseImage(&workImg);
    cvReleaseImage(&imgshow);
    return 0;
}
int judge(double re,double im)
{
    double x=0,y=0,X,Y;
    int i=0;
    for(i=0;x*x+y*y<=4;i++)
    {
        X=x*x-y*y+re;
        Y=x*y*2+im;
        x=X;
        y=Y;
        if(i==max_times)
            break;
    }
        return i;
}
void on_mouse(int event, int x,int y,int flags,void* param)
{
    int thickness=2;
    float real,imaginary;
    int left,right,up,down;
    int a,b,c;//前景色
    int d,e,f;//背景色
    double DX=XMax-XMin;
    double DY=YMax-YMin;
    double offX=DX/M;
    double offY=DY/M;
    CvPoint p1,p2;
    if(event==CV_EVENT_MBUTTONDOWN)//中鍵單擊平移
        draw(x,y);
    if(event==CV_EVENT_RBUTTONUP)//右鍵單擊返回
    {
        draw(M/2,M/2);
        XMax=2.0;
        XMin=-2.0;
        YMax=2.0;
        YMin =-2.0;
        DX=XMax-XMin;
        DY=YMax-YMin;
        offX=DX/M;
        offY=DY/M;
    }
    if(event==CV_EVENT_LBUTTONDOWN)//
    {
        ROI_rect.x=x;//當前鼠標位置(x,y)
        ROI_rect.y=y;
        flag=1;
    }
    if(flag&&event==CV_EVENT_MOUSEMOVE)//鼠標狀態
    {
        cvCopy(workImg,imgshow,NULL);//不斷更新顯示圖像
        p1=cvPoint(ROI_rect.x,ROI_rect.y);//第一個點
        p2=cvPoint(x,x-ROI_rect.x+ROI_rect.y);
        cvRectangle(imgshow,p1,p2,CV_RGB(0,500,150),thickness,CV_AA,0);
        cvShowImage("Opencv",imgshow);
    }
    if(flag&&event==CV_EVENT_LBUTTONUP)
    {
        flag=0;
        p2.x=x;
        p2.y=x-ROI_rect.x+ROI_rect.y;
        p1.x=ROI_rect.x;
        p1.y=ROI_rect.y;
        left=min(p1.x,p2.x);
        right=max(p1.x,p2.x);
        up=min(p1.y,p2.y);
        down=max(p1.y,p2.y);
        cvShowImage("Opencv",workImg);
        cvWaitKey (1);
        XMax=offX*right+XMin;
        XMin=offX*left+XMin;
        YMax=offY*down+YMin;
        YMin=offY*up+YMin;
        drawmandelbrot();
        cvShowImage("Opencv",workImg);
    }
    cvWaitKey(20);
}
void draw(int x,int y)
{
    double real,imaginary,i;
    int m,n;
    int a,b,c;//前景色
    int d,e,f;//背景色
     for(m=0;m<M;m++)
        for(n=0;n<M;n++)
        {
            real=(m-x)/100.0;
            imaginary=(n-y)/100.0;
            i=judge(real,imaginary);
            if((i-max_times)==0)
            {


                a=m;
                b=n;
                c=m+n;
                sca.val[0]=a;
                sca.val[1]=b;
                sca.val[2]=c;
                cvSet2D(workImg,n,m,sca);
            }
            else//不在集合內
            {
                d=(sin(6*i))*60+0.5*abs(200-m)+70;
                e=(cos(5*i))*60+0.5*abs(200-n)+70;
                f=(sin(100*i))*60+0.5*abs(200-n)+70;
                sca.val[0]=d;
                sca.val[1]=e;
                sca.val[2]=f;
                cvSet2D(workImg,n,m,sca);
            }
        }
    cvShowImage("Opencv",workImg);
}
void drawmandelbrot()
{
    int m,n;
    int a,b,c;//前景色
    int d,e,f;//背景色
    int i;
    double real,imaginary;
    double deltaX=(XMax-XMin)/M;
    double deltaY=(YMax-YMin)/M;
    for(m=0;m<M;m++)
    {
        for(n=0;n<M;n++)
        {
            i=judge(real,imaginary);
            real=XMin+m*deltaX;
            imaginary=YMin+n*deltaY;
            CvScalar sca;
            if(judge(real,imaginary)-200==0)
            {
                a=m;
                b=n;
                c=n+m;
                sca.val[0]=a;
                sca.val[1]=b;
                sca.val[2]=c;
                cvSet2D(workImg,n,m,sca);
            }
            else
            {
                d=(sin(6*i))*60+0.5*abs(200-m)+70;
                e=(cos(5*i))*60+0.5*abs(200-n)+70;
                f=(sin(100*i))*60+0.5*abs(200-n)+70;
                sca.val[0]=d;
                sca.val[1]=e;
                sca.val[2]=f;
                cvSet2D(workImg,n,m,sca);
            }
        }
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章