c畫圖源碼
① 求一用c語言畫直線的程序
不調用畫圖 API,用C 或 C++ 如何實現畫一條線?
Milo Yip:如何開始用 C++ 寫一個光柵化渲染器?
我嘗試用不同技術實現畫直線的方法(完整源代碼在 miloyip/line),此文簡單介紹個中思路。本文的代碼採用 C 語言、標准庫及極簡的 PNG 編碼函數 svpng(),沒有使用其他 API。
1. Bresenham 演算法
Bresenham直線演算法 [1] 是最簡單的直線光柵化(rasterization)演算法。
Bresenham 直線
如果像上圖,直線的高度小於寬度,那麼 Bresenham 直線演算法會為 軸每個坐標填入一個像素,繪畫每個像素時按斜率判斷 是否需要調整。整個演算法可以避開浮點數運算,只用整數運算實現。以下是一個簡單實現:
// Modified from https://rosettacode.org/wiki/Bitmap/Bresenham%27s_line_algorithm#C
void bresenham(int x0, int y0, int x1, int y1) {
int dx = abs(x1 - x0), sx = x0 < x1 ? 1 : -1;
int dy = abs(y1 - y0), sy = y0 < y1 ? 1 : -1;
int err = (dx > dy ? dx : -dy) / 2;
while (setpixel(x0, y0), x0 != x1 || y0 != y1) {
int e2 = err;
if (e2 > -dx) { err -= dy; x0 += sx; }
if (e2 < dy) { err += dx; y0 += sy; }
}
}
為了測試不同角度,我做了一個測試用例:
int main() {
memset(img, 255, sizeof(img));
float cx = w * 0.5f - 0.5f, cy = h * 0.5f - 0.5f;
for (int j = 0; j < 5; j++) {
float r1 = fminf(W, H) * (j + 0.5f) * 0.085f;
float r2 = fminf(W, H) * (j + 1.5f) * 0.085f;
float t = j * PI / 64.0f;
for (int i = 1; i <= 64; i++, t += 2.0f * PI / 64.0f) {
float ct = cosf(t), st = sinf(t);
bresenham((int)(cx + r1 * ct), (int)(cy - r1 * st), (int)(cx + r2 * ct), (int)(cy - r2 * st));
}
}
svpng(fopen("line_bresenham.png", "wb"), W, H, img, 0);
}
完整代碼 line_bresenham.c
渲染結果及中間局部放大:
2. 采樣方法
Bresenham 直線演算法有 3 個問題:
不能控制直線寬度;
坐標為整數;
只能對像素寫入一個顏色,只用單色會有嚴重的鋸齒效果。
在圖形學中,除了以逐個圖元(如直線)方式渲染,我們還可以通過對每個像素進行采樣(sampling),換句話說,我們可對整個圖像逐像素詢問:「這個像素的顏色是什麼?」
用采樣方式畫直線時,我們可以用一個具有面積的形狀去表示「直線」,例如是長方形。但在本文中,我們使用膠囊體(capsule)去表示直線。這樣就能解決上面前兩個問題:(1) 可用膠囊體半徑設置直線的寬度;(2) 坐標可以為浮點數。不過,用最簡單的采樣方式,我們需要在每像素查詢所有圖元是否佔有該像素,效率很低。
② 用c語言編寫一個畫圖工具 哪位大俠會呀 編一個最簡單的 能給個簡單一點的畫圖工具的源代碼么 跪謝啦
自己寫吧,不然怎麼進步?隨便找個MFC的書,裡面都可以找到畫圖相關的內容,定義一個對話框,然後在上面隨便定義個畫筆,刷點東西。做到這一步你就知道接下來怎麼做了
③ 誰會用c語言設計數學函數繪圖 可畫一次和二次函數圖像 的源代碼
你用cad軟體做這樣的圖太簡單了
④ 求一個純C語言繪圖函數
SDL可以做到。給你貼個源碼:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<SDL/SDL.h>
#include<SDL/SDL_image.h>
//函數聲明
int Init(void);
SDL_Surface *createScreen(int width,int height,int bpp,Uint32 flags);
void destroyScreen(SDL_Surface *screen);
SDL_Surface *loadImageBMP(char *filename);
void loadImage(char *filename,SDL_Surface *screen,int xPos,int yPos);
SDL_Surface *screen;
SDL_Surface *image_handler;
char buffer[10];
int main(int argc,char *argv[])
{
int height=640,width=480;
int bpp=8;
Init();
screen = createScreen(width,height,bpp,SDL_SWSURFACE);
loadImage("./wuyajie.bmp",screen,width/2,height/4);
read(STDIN_FILENO,buffer,1);
destroyScreen(screen);
SDL_Quit();
return 0;
}
int Init(void)
{
if(SDL_Init(SDL_INIT_VIDEO)==-1)
{
fprintf(stderr,"SDL Init Error:%s\n",SDL_GetError());
exit(-1);
}
return 0;
}
/*
創建屏幕,並將屏幕設置為640x480大小
*/
SDL_Surface *createScreen(int width,int height,int bpp,Uint32 flags)
{
SDL_Surface *screen;
if((screen = SDL_SetVideoMode(width,height,bpp,flags))==NULL)
{
fprintf(stderr,"Could not create a screen:%s\n",SDL_GetError());
exit(-1);
}
return screen;
}
/*
載入圖片
*/
void loadImage(char *filename,SDL_Surface *screen,int xPos,int yPos)
{
SDL_Surface *image;
SDL_Rect dest;
image = SDL_LoadBMP(filename);
if ( image == NULL ){
fprintf(stderr, "無法載入 %s: %s\n", filename, SDL_GetError());
exit(-1);
}
dest.x = xPos;
dest.y = yPos;
dest.w = image->w;
dest.h = image->h;
SDL_BlitSurface(image,NULL,screen,&dest);
SDL_UpdateRects(screen,1,&dest);
}
void destroyScreen(SDL_Surface * screen)
{
SDL_FreeSurface(screen);
}
⑤ 求一段畫圓的程序源代碼,要求是C 或者C++ 的語言
以x=0,y=0為圓心,r為半徑,屏幕左上角為坐標原點
for (x=-r;x<r;x++)
{
//計算y
y=sqrt(r*r-x*x);
//畫點
setpix(x+r, y+r);
setpix(x+r, 0-y+r);
}
老兄,setpix()不是畫圖函數,而是畫點函數,不畫點怎麼畫圖啊
⑥ 跪求關於c程序源代碼,運行後的效果為動態圖形,比如圓啊,三角形之類的,最好附上代碼的解釋
這個一個VC中畫圓的代碼(可能你還需要配置編譯環境):
#include <GL/glut.h> // 設置頭文件
#include <stdlib.h>
#include <math.h>
/*void setPixel ( int x, int y)
{
glBegin ( GL_POINTS);
glVertex2i (x, y);
glEnd ();
}
inline int round (const float a ) { return int (a + 0.5); }
void lineDDA (int x0, int y0, int xEnd, int yEnd)
{
int dx = xEnd - x0, dy = yEnd - y0, steps, k;
float xIncrement, yIncrement, x = x0, y = y0;
if (fabs (dx) > fabs (dy))
steps = fabs (dx);
else
steps = fabs (dy);
xIncrement = float (dx) / float (steps);
yIncrement = float (dy) / float (steps);
setPixel (round (x), round (y));
for (k = 0; k < steps; k++) {
x += xIncrement;
y += yIncrement;
setPixel (round (x), round (y));
}
} */
class screenPt
{
private:
GLint x,y;
public:
screenPt()
{
x=y=0;
}
void setCoords (GLint xCoordValue,GLint yCoordValue)
{
x=xCoordValue;
y=yCoordValue;
}
GLint getx() const{
return x;
}
GLint gety() const{
return y;
}
void incrementx()
{
x++;
}
void decrementy()
{
y--;
}
};
void setPixel(GLint xCoord,GLint yCoord)
{
glBegin (GL_POINTS);
glVertex2i(xCoord,yCoord);
glEnd();
}
void circleMidpoint(GLint xc,GLint yc,GLint radius)
{
screenPt circPt;
GLint p=1-radius; //決策參數
circPt.setCoords(0,radius);
void circlePlotPoints (GLint ,GLint,screenPt);
circlePlotPoints(xc,yc,circPt);
while(circPt.getx()<circPt.gety())
{
circPt.incrementx();
if(p<0)
p += 2*circPt.getx() + 1;
else
{
circPt.decrementy();
p += 2*(circPt.getx() - circPt.gety()) + 1;
}
circlePlotPoints(xc,yc,circPt);
}
}
void circlePlotPoints(GLint xc,GLint yc,screenPt circPt)
{
setPixel (xc + circPt.getx(),yc + circPt.gety());
setPixel (xc - circPt.getx(),yc + circPt.gety());
setPixel (xc + circPt.getx(),yc - circPt.gety());
setPixel (xc - circPt.getx(),yc - circPt.gety());
setPixel (xc + circPt.gety(),yc + circPt.getx());
setPixel (xc - circPt.gety(),yc + circPt.getx());
setPixel (xc + circPt.gety(),yc - circPt.getx());
setPixel (xc - circPt.gety(),yc - circPt.getx());
}
void init (void) // 初始化函數
{
glClearColor (1.0, 1.0, 1.0, 0.0); // 設置清屏的顏色(Red,green,blue),但不能讓該顏色在顯示窗上
// 出現
glMatrixMode (GL_PROJECTION); // 設置投影矩陣
glLoadIdentity (); // 單位化上述投影矩陣
gluOrtho2D (0.0, 800.0, 0.0, 600.0); // 設置具體投影 矩陣為平面正交投影 4/3
}
void lineSegment (void) //繪圖函數
{
glClear (GL_COLOR_BUFFER_BIT); // 按glClearColor (1.0, 1.0, 1.0, 0.0);指定的顏色刷新顏色
glColor3f (1.0, 0.0, 0.0); //設置前景色,即畫圖的顏色
circleMidpoint(400,300,200);
glFlush ( ); // 在每一畫面或場景的結尾處調用,強制前面發出的OpenGL 命令開始執行
}
void main (int argc, char** argv) // OpenGL 繪圖主函數
{
glutInit (&argc, argv); // 初始化GLUT 庫
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); // 設置 顯示模式
glutInitWindowPosition (50, 100); // 窗口左上角像素坐標
glutInitWindowSize (800, 600); // 設置設備顯示窗口大小 4/3
glutCreateWindow ("An Example OpenGL Program"); // 創建一個窗口,參數為窗口的標題
init ( ); // 函數調用.
glutDisplayFunc (lineSegment); // 繪制當前窗口
glutMainLoop ( ); //通常用於程序的結尾,表示開始運行程序.顯示出所有創建的窗口
}
⑦ ubuntu系統如何用c語言繪圖
可以使用 plplot 函數庫,需要自己安裝,安裝後在源代碼中 include plplot.h 就能用了
⑧ 分形彩圖的C或者matlab的源代碼(至少3段)
#include<graphics.h>
#include<stdlib.h>
#include<math.h>
int main()
{
float m,dx,dy,x,y,x_n,y_n,Cx,Cy;
int n,i,j,L=4;
int gdriver=DETECT,gmode; //gdriver和gmode分別表示圖形驅動器和模式,gdriver=DETECT是在測試顯示器硬體
initgraph(&gdriver,&gmode,""); //初始化圖形模式
setbkcolor(1); //設置背景色為藍色
dx=3.0/639;
dy=2.2/479;
for(i=0;i<639;i++)
{
Cx=-1.9+i*dx;
for(j=0;j<479;j++)
{
Cy=-1.2+j*dy;
x=y=0;
for(n=0;n<=1000;n++)
{
x_n=x*x-y*y+Cx;
y_n=2*x*y+Cy;
m=x_n*x_n;
if(m>L) break;
x=x_n;
y=y_n;
}
putpixel(i,j,(int)(0.4*m)%16); //在指定位置畫一像素(坐標(i,j),第三個計算式為畫點的顏色)
}
}
getch(); //任意鍵返回
closegraph(); //關閉圖形模式並返迴文本模式
}
關於顏色的設置如下:
━━━━━━━━━━━━━━━━━━━━━━━━━━
符號常數 數值 含義 字元或背景
——————————————————————————
BLACK 0 黑 兩者均可
BLUE 1 蘭 兩者均可
GREEN 2 綠 兩者均可
CYAN 3 青 兩者均可
RED 4 紅 兩者均可
MAGENTA 5 洋紅 兩者均可
BROWN 6 棕 兩者均可
LIGHTGRAY 7 淡灰 兩者均可
DARKGRAY 8 深灰 只用於字元
LIGHTBLUE 9 淡蘭 只用於字元
LIGHTGREEN 10 淡綠 只用於字元
LIGHTCYAN 11 淡青 只用於字元
LIGHTRED 12 淡紅 只用於字元
LIGHTMAGENTA 13 淡洋紅 只用於字元
YELLOW 14 黃 只用於字元
WHITE 15 白 只用於字元
BLINK 128 閃爍 只用於字元
⑨ 求C源碼:計算機圖形學程序——掃描線演算法
這是我以前上學的時候寫的,你改改,湊活用巴。
=============================
#include <graphics.h>
#include <stdio.h>
#include <dos.h>
#include <math.h>
#include <bios.h>
#include <string.h>
void parspl ( int p[10000][2] , long n , int precision , int color )
{
int x = 0 , y = 0 , i = 0 , j = 0 , m = 0 ;
double t2 = 0 , t3 = 0 , t = 0 , a , b , c , d , e = p[1][0] + 5 , f = p[1][1] + 5 ;
setcolor ( color ) ;
m=n+1;
p[0][0] = p[n][0] ;
p[0][1] = p[n][1] ;
p[m][0] = p[1][0] ;
p[m][1] = p[1][1] ;
p[m+1][0] = p[2][0] ;
p[m+1][1] = p[2][1] ;
moveto ( p[1][0] , p[1][1] ) ;
for ( i = 0 ; i < n ; i ++ )
{
t = 0.5 / precision ;
for ( j = 1 ; j < precision ; j ++ )
{
t2 = t * t ;
t3 = t2 * t ;
a = 4 * t2 - t - 4 * t3 ;
b = 1 - 10 * t2 + 12 * t3 ;
c = t + 8 * t2 - 12 * t3 ;
d = 4 * t3 - 2 * t2 ;
x = a * p[i][0] + b * p[i+1][0] + c * p[i+2][0] + d * p[i+3][0] ;
y = a * p[i][1] + b * p[i+1][1] + c * p[i+2][1] + d * p[i+3][1] ;
lineto ( x , y ) ;
line ( e , f , x + 5 , y + 5 ) ;
moveto ( x , y ) ;
t += 0.5 / precision ;
e = x + 5 ;
f = y + 5 ;
}
lineto ( p[i+2][0] , p[i+2][1] ) ;
moveto ( e , f ) ;
lineto ( p[i+2][0] + 5 , p[i+2][1] + 5 ) ;
moveto ( p[i+2][0] , p[i+2][1] ) ;
}
}
int main()
{
long n = 5 ;
char pwd[4] ;
int p[100][2] ;
int a1 , a2 , b1 , b2 , c1 , c2 , d1 , d2 , e1 , e2 ;
int gdriver = VGA , gmode = VGAHI ;
initgraph( &gdriver , &gmode , "c:\\tc" ) ;
setbkcolor ( 0 ) ;
a1 = p[1][0] = 320 ;
a2 = p[1][1] = 240 ;
b1 = p[2][0] = 320 ;
b2 = p[2][1] = 120 ;
c1 = p[3][0] = 452 ;
c2 = p[3][1] = 128 ;
d1 = p[4][0] = 382 ;
d2 = p[4][1] = 388 ;
e1 = p[5][0] = 364 ;
e2 = p[5][1] = 280 ;
loop:
if ( a1 <= p[1][0] && p[1][0] <= 520 )
{
a1 = p[1][0] ;
p[1][0] += 1 ;
}
else
{
if ( p[1][0] >= 120 )
{
a1 = p[1][0] ;
p[1][0] -= 1 ;
}
else
a1 = p[1][0] = 120 ;
}
if ( a2 >= p[1][1] && p[1][1] >= 60 )
{
a2 = p[1][1] ;
p[1][1] -= 2 ;
}
else
{
if ( p[1][1] <= 420 )
{
a2 = p[1][1] ;
p[1][1] += 2 ;
}
else
a2 = p[1][1] = 420 ;
}
if ( b1 >= p[2][0] && p[2][0] >= 120 )
{
b1 = p[2][0] ;
p[2][0] -= 2 ;
}
else
{
if ( p[2][0] <= 520 )
{
b1 = p[2][0] ;
p[2][0] += 2 ;
}
else
b1 = p[2][0] = 520 ;
}
if ( b2 <= p[2][1] && p[2][1] <= 420 )
{
b2 = p[2][1] ;
p[2][1] += 1 ;
}
else
{
if ( p[2][1] >= 60 )
{
b2 = p[2][1] ;
p[2][1] -= 1 ;
}
else
b2 = p[2][1] = 60 ;
}
if ( c1 <= p[3][0] && p[3][0] <= 520 )
{
c1 = p[3][0] ;
p[3][0] += 1 ;
}
else
{
if ( p[3][0] >= 120 )
{
c1 = p[3][0] ;
p[3][0] -= 1 ;
}
else
c1 = p[3][0] = 120 ;
}
if ( c2 <= p[3][1] && p[3][1] <= 420 )
{
c2 = p[3][1] ;
p[3][1] += 1 ;
}
else
{
if ( p[3][1] >= 60 )
{
c2 = p[3][1] ;
p[3][1] -= 1 ;
}
else
c2 = p[3][1] = 60 ;
}
if ( d1 >= p[4][0] && p[4][0] >= 120 )
{
d1 = p[4][0] ;
p[4][0] -= 1 ;
}
else
{
if ( p[4][0] <= 520 )
{
d1 = p[4][0] ;
p[4][0] += 1 ;
}
else
d1 = p[4][0] = 520 ;
}
if ( d2 >= p[4][1] && p[4][1] >= 60 )
{
d2 = p[4][1] ;
p[4][1] -= 1 ;
}
else
{
if ( p[4][1] <= 420 )
{
d2 = p[4][1] ;
p[4][1] += 1 ;
}
else
d2 = p[4][1] = 420 ;
}
if ( e1 <= p[5][0] && p[5][0] <= 520 )
{
e1 = p[5][0] ;
p[5][0] += 1 ;
}
else
{
if ( p[5][0] >= 120 )
{
e1 = p[5][0] ;
p[5][0] -= 1 ;
}
else
e1 = p[5][0] = 120 ;
}
if ( e2 <= p[5][1] && p[5][1] <= 420 )
{
e2 = p[5][1] ;
p[5][1] += 2 ;
}
else
{
if ( p[5][1] >= 60 )
{
e2 = p[5][1] ;
p[5][1] -= 2 ;
}
else
e2 = p[5][1] = 60 ;
}
parspl ( p , n , 100 , 4 ) ;
parspl ( p , n , 100 , 4 ) ;
if ( bioskey ( 1 ) > 0 )
{
printf ("Please Input Password:") ;
gets (pwd) ;
if ( !strcmp(pwd,"cmy") )
{
clearviewport () ;
closegraph () ;
return 1 ;
}
}
cleardevice () ;
goto loop ;
}
⑩ 哦求c語言圖形編程源代碼O(∩_∩)O3
//program1
#include<stdio.h>
intmain()
{
inti,j;
for(i=1;i<=4;i++)
{
for(j=1;j<=4-i;j++)
printf("");
for(j=1;j<=i*2-1;j++)
printf("%d",i);
}
for(i=3;i>=1;i--)
{
for(j=1;j<=4-i;j++)
printf("");
for(j=1;j<=i*2-1;j++)
printf("%d",i);
}
return0;
}
//program2
#include<stdio.h>
intmain()
{
inti,j;
for(i=1;i<=4;i++)
{
for(j=1;j<=4-i;j++)
printf("");
for(j=1;j<=i*2-1;j++)
printf("%d",5-i);
}
for(i=3;i>=1;i--)
{
for(j=1;j<=4-i;j++)
printf("");
for(j=1;j<=i*2-1;j++)
printf("%d",5-i);
}
return0;
}