1. 程式人生 > >基於VC6.0的控制檯作圖--一個極座標曲線圖(26行程式碼)

基於VC6.0的控制檯作圖--一個極座標曲線圖(26行程式碼)

文章目錄

先看MATLAB如何做

極座標函式
ρ = exp (

cos ( θ ) ) 2 cos
( 4 θ ) + ( sin ( θ / 12 ) ) 5 \rho=\exp(\cos(\theta))-2\cos(4\theta)+(\sin(\theta/12))^5
的曲線是何樣的?估計用MATLAB作圖最簡單,三句話即可:

theta=0:0.01:20*pi;
rho=exp(cos(theta))-2*cos(4*theta)+(sin(theta/12)).^5;
polarplot(theta,rho);

結果:
在這裡插入圖片描述

如果不用MATLAB呢?

如果不用MATLAB呢?估計想得到作圖能力強大的軟體還有R語言、Python語言。Gnuplot也是一個不錯的選擇,直接用svg也可做圖,或採用百度開發的Echarts也能完成。總之,方法很多。但用Gnuplot是藉助了第3方作圖工具了,用svg,Echarts或其他javascript包也要藉助瀏覽器來顯示。

假如在有些情況下,不允許用任何第3方工具。不允許用windows程式設計架構或MFC,僅用C/C++語言結合windows的基本繪圖函式,也能作圖嗎?

我們追求簡單。在此,我們僅用26行程式碼,在VC基本編譯環境下,在控制檯上也作出瞭如MATLAB那樣的曲線結果。

單純依靠C函式完成作圖

windows下作圖是使用gdi32.lib, user32.lib中的函式,所以編譯要連結相應的庫檔案。庫檔案可以通過編譯器選項鍊接,如:

cl.exe  simpledraw.cpp /link user32.lib gdi32.lib

也可在Cpp程式碼中加入預編指令:

#pragma comment(lib,"user32.lib") 
#pragma comment(lib,"gdi32.lib")

為了引用GDI函式(GDI:圖形裝置介面),需在main函式前加入:

extern "C" WINBASEAPI HWND WINAPI GetConsoleWindow ();

在main函式中,採用

HWND hwnd = GetConsoleWindow(); 
HDC hdc = GetDC(hwnd); 

來獲取控制檯視窗控制代碼,從而操縱控制檯使之以圖形模式而不是字元模式作圖。

【注】還可有第2種方法獲得控制檯視窗的繪圖hdc:先用GetConsoleTitle得到控制檯視窗標題,再通過FindWindow函數借助標題獲取視窗控制代碼HWND,之後再利用GetDC函數借助HWND獲取HDC。這種做法可避免使用GetConsoleWindow函式。區域性程式碼如下:

TCHAR title[256];//控制檯程式標題
......
int main(int argc,char *argv[]) 
{ 
	GetConsoleTitle(title, 256);//獲取控制檯標題
	HDC hdc = GetDC(FindWindow(0, title));
......

如果以預設畫筆作圖,則直接呼叫作圖函式即可。最簡單的作圖函式就是畫直線(LineTo)。如

MoveToEx(hdc,400,300,NULL); //筆移到座標(400,300)點
LineTo(hdc,(int)x,(int)y); //畫線到(x,y)座標

函式中,hdc就是指向控制檯的作圖控制代碼。

好了,完整程式碼如下:

#include<windows.h>
#include<math.h>
#pragma comment(lib,"user32.lib") 
#pragma comment(lib,"gdi32.lib")
extern "C" WINBASEAPI HWND WINAPI GetConsoleWindow ();
int main(int argc,char *argv[]) 
{ 
	HWND hwnd = GetConsoleWindow(); 
	HDC hdc = GetDC(hwnd); 
	double rho, theta, x, y;//極座標和直角座標
	system("cls");//清屏
	system("color f0");//白底黑字
	Rectangle(hdc, 120, 50, 120+600, 50+500);//畫個邊框
	MoveToEx(hdc,400,300,NULL); //筆移到座標原點(螢幕座標400,300)
	for (int i=0; i<10000; i++)
	{
		theta=0.01*i;
		rho=exp(cos(theta))-2*cos(4*theta)+pow(sin(theta/12.0),5);
		x=400+50*rho*cos(theta);
		y=300-50*rho*sin(theta);
		LineTo(hdc,(int)x,(int)y); //畫線作圖
	}
	TextOut(hdc, 550, 45, "美麗的蝴蝶結", 12);//寫字
    ReleaseDC(hwnd,hdc);
	return 0; 
}

其中,LineTo用以畫線,TextOut用以在指定座標處寫字。退出程式前,用ReleaseDC(hwnd,hdc);釋放作圖資源,不用也行,但這是良好的程式設計習慣。預設畫筆是黑色的,所以畫圖前將背景設為白色,並清屏。程式中,以螢幕座標點(400,300)作為數學座標原點。以極座標計算後轉換為直角座標(並適當放大)作圖。
編譯:
1、直接在VC++6.0中編譯。或
2、控制檯編譯:

cl.exe  simpledraw.cpp

3、或連結上庫檔案(程式碼中可不要#pragma)

cl.exe  simpledraw.cpp /link user32.lib gdi32.lib

執行結果:
在這裡插入圖片描述

再來幾個例子

三葉草

theta=0:0.01:2*pi;
rho=1+cos(3*theta)+1.5*(sin(3*theta)).^2;
polarplot(theta,rho);

在這裡插入圖片描述

Cpp程式碼:

#include<windows.h>
#include<math.h>
#pragma comment(lib,"user32.lib") 
#pragma comment(lib,"gdi32.lib")
extern "C" WINBASEAPI HWND WINAPI GetConsoleWindow ();
int main(int argc,char *argv[]) 
{ 
	HWND hwnd = GetConsoleWindow(); 
	HDC hdc = GetDC(hwnd); 
	double rho, theta, x, y;//極座標和直角座標
	system("cls");//清屏
	system("color f0");//白底黑字
	Rectangle(hdc, 120, 50, 120+600, 50+500);//畫個邊框
	for (int i=0; i<10000; i++)
	{
		theta=0.01*i;
		rho=1+cos(3*theta)+pow(1.5*(sin(3*theta)),2);
		x=400+50*rho*cos(theta);
		y=300-50*rho*sin(theta);
		if(i==0){
			MoveToEx(hdc,(int)x,(int)y,NULL); //筆移到起點
		}else
		{
			LineTo(hdc,(int)x,(int)y); //畫線作圖
		}	
	}
	TextOut(hdc, 550, 45, "美麗的三葉草", 12);//寫字
    ReleaseDC(hwnd,hdc);
	return 0; 
}

程式中演示如何設定畫筆起始位置。
執行結果:
在這裡插入圖片描述

正弦波:

#include<windows.h>
#include<math.h>
#pragma comment(lib,"user32.lib") 
#pragma comment(lib,"gdi32.lib")
extern "C" WINBASEAPI HWND WINAPI GetConsoleWindow ();
int main(int argc,char *argv[]) 
{ 
	HWND hwnd = GetConsoleWindow(); 
	HDC hdc = GetDC(hwnd); 
	double x, y;//直角座標
	system("cls");//清屏
	system("color f0");//白底黑字
	Rectangle(hdc, 120, 50, 120+600, 50+500);//畫個邊框
	for (int i=0; i<50000; i++)
	{
		x=0.01*i;
		y=300+200*sin(2*3.14159*0.01*x);
		if(i==0){
			MoveToEx(hdc,130+(int)x,(int)y,NULL); //筆移到起點
		}else
		{
			LineTo(hdc,130+(int)x,(int)y); //畫線作圖
		}	
	}
	TextOut(hdc, 550, 45, "美麗的正弦波", 12);//寫字
    ReleaseDC(hwnd,hdc);
	return 0; 
}

在這裡插入圖片描述

改畫筆畫刷(顏色、粗細、透明)

也很簡單。在作圖前設定一下就行。

HPEN hPen = CreatePen(PS_SOLID, 2, RGB(0,255,0));//新增畫筆屬性。2代表寬度,RGB(0,255,0)用於調顏色為綠色
SelectObject(hdc, hPen);//畫筆繫結到控制代碼
HBRUSH hBrush=(HBRUSH)GetStockObject(NULL_BRUSH) ;//透明的畫刷
SelectObject (hdc, hBrush);

完整程式碼:

#include<windows.h>
#include<math.h>
#pragma comment(lib,"user32.lib") 
#pragma comment(lib,"gdi32.lib")
extern "C" WINBASEAPI HWND WINAPI GetConsoleWindow ();
int main(int argc,char *argv[]) 
{ 
	HWND hwnd = GetConsoleWindow(); 
	HDC hdc = GetDC(hwnd); 
	double x, y;//直角座標
	system("cls");//清屏
	system("color 0f");//黑底白字
	HPEN hPen = CreatePen(PS_SOLID, 2, RGB(0,255,0));//新增畫筆屬性。2代表寬度,RGB(0,255,0)用於調顏色為綠色
    SelectObject(hdc, hPen);//畫筆繫結到控制代碼
	HBRUSH hBrush=(HBRUSH)GetStockObject(NULL_BRUSH) ;//透明
    SelectObject (hdc, hBrush);
	Rectangle(hdc, 120, 50, 120+600, 50+500);//畫個邊框
	for (int i=0; i<50000; i++)
	{
		x=0.01*i;
		y=300+200*sin(2*3.14159*0.01*x);
		if(i==0){
			MoveToEx(hdc,130+(int)x,(int)y,NULL); //筆移到起點
		}else
		{
			LineTo(hdc,130+(int)x,(int)y); //畫線作圖
		}	
	}
	TextOut(hdc, 550, 45, "美麗的正弦波", 12);//寫字
    ReleaseDC(hwnd,hdc);
	return 0; 
}

結果:
在這裡插入圖片描述

可見字色還是預設的。如果要改字背景和前景色,可用:

SetBkColor(hdc, RGB(0,0,0));
SetTextColor(hdc, RGB(0,255,0));
//然後再寫字:
TextOut(hdc, 550, 45, "美麗的正弦波", 12);//寫字

圖就成了這樣:
在這裡插入圖片描述

如果還想設定字型,程式碼就要麻煩點,設定字型後,用SelectObject(hdc, font)選擇字型即可,如下:

......
	HFONT font = CreateFont(
		28, // nHeight
		0, // nWidth
		50, // nEscapement
		0, // nOrientation
		FW_BOLD, // nWeight
		TRUE, // bItalic
		FALSE, // bUnderline
		0, // cStrikeOut
		ANSI_CHARSET, // nCharSet
		OUT_DEFAULT_PRECIS, // nOutPrecision
		CLIP_DEFAULT_PRECIS, // nClipPrecision
		DEFAULT_QUALITY, // nQuality
		DEFAULT_PITCH | FF_SWISS,
		"Arial" // nPitchAndFamily Arial
		);
	SelectObject(hdc, font);
......

作圖結果:
在這裡插入圖片描述

可見,用C語言從底層控制作圖是極為靈活的。

完整程式碼:

#include<windows.h>
#include<math.h>
#pragma comment(lib,"user32.lib") 
#pragma comment(lib,"gdi32.lib")
extern "C" WINBASEAPI HWND WINAPI GetConsoleWindow ();
int main(int argc,char *argv[]) 
{ 
	HWND hwnd = GetConsoleWindow(); 
	HDC hdc = GetDC(hwnd); 
	double x, y;//直角座標
	system("cls");//清屏
	system("color 0f");//黑底白字
	HPEN hPen = CreatePen(PS_SOLID, 2, RGB(0,255,0));//新增畫筆屬性。2代表寬度,RGB(0,255,0)用於調顏色為綠色
    SelectObject(hdc, hPen);//畫筆繫結到控制代碼
	HBRUSH hBrush=(HBRUSH)GetStockObject(NULL_BRUSH) ;//透明
    SelectObject (hdc, hBrush);
	Rectangle(hdc, 120, 50, 120+600, 50+500);//畫個邊框
	for (int i=0; i<50000; i++)
	{
		x=0.01*i;
		y=300+200*sin(2*3.14159*0.01*x);
		if(i==0){
			MoveToEx(hdc,130+(int)x,(int)y,NULL); //筆移到起點
		}else
		{
			LineTo(hdc,130+(int)x,(int)y); //畫線作圖
		}	
	}

	HFONT font = CreateFont(
		28, // nHeight
		0, // nWidth
		50, // nEscapement
		0, // nOrientation
		FW_BOLD, // nWeight
		TRUE, // bItalic
		FALSE, // bUnderline
		0, // cStrikeOut
		ANSI_CHARSET, // nCharSet
		OUT_DEFAULT_PRECIS, // nOutPrecision
		CLIP_DEFAULT_PRECIS, // nClipPrecision
		DEFAULT_QUALITY, // nQuality
		DEFAULT_PITCH | FF_SWISS,
		"Arial" // nPitchAndFamily Arial
		);
	SelectObject(hdc, font);

	SetBkColor(hdc, RGB(0,0,0));
    SetTextColor(hdc, RGB(0,255,0));
	TextOut(hdc, 520, 45, "美麗的正弦波", 12);//寫字
    ReleaseDC(hwnd,hdc);
	return 0; 
}

稍作變化

#include<windows.h>
#include<stdio.h>
#include<math.h>
#pragma comment(lib,"user32.lib") 
#pragma comment(lib,"gdi32.lib")
extern "C" WINBASEAPI HWND WINAPI GetConsoleWindow ();
int main(int argc,char *argv[]) 
{ 
	HWND hwnd = GetConsoleWindow(); 
	HDC hdc = GetDC(hwnd); 
	double rho, theta, x, y;//極座標和直角座標
	HPEN hPen1,hPen2
            
           

相關推薦

基於VC6.0控制檯作圖--一個極座標曲線圖26程式碼

文章目錄 先看MATLAB如何做 如果不用MATLAB呢? 單純依靠C函式完成作圖 再來幾個例子 改畫筆畫刷(顏色、粗細、透明) 稍作變化 還能有比這更簡單的C程式碼嗎? 還可讓圖形動起來

Android學習筆記第一程式碼一個簡單的登入介面

一.建立xml檔案 1.賬戶輸入框和密碼輸入框的編寫 <TextView android:layout_height="wrap_content" android:text="@string/LG_name" />

3、關於匿名內部類一個小題目補全程式碼

/* 匿名內部類面試題: 按照要求,補齊程式碼 interface Inter { void show(); } class Outer { //補齊程式碼 } class OuterDemo { public static void mai

Vczh Library++ 3.0之可配置語法分析器FpMacro及程式碼

    上一篇文章基本上把分析的過程都講完了,於是這次就把FpMacro作為一個Demo拿了出來。不第一次就發的原因主要是那個時候FpMacro剛剛寫完,當然寫完就要用的,於是後來就在Vczh Library++ 3.0的庫裡面大量使用了FpMacro作為程式碼生成的一個工具,用來代替一部分的巨集

基於VC6.0控制檯作圖--顯示點陣圖bmp

文章目錄 GDI是什麼? 用`LoadImage`讀取點陣圖bmp檔案 將點陣圖選入記憶體相容區 將記憶體相容區拷貝到螢幕區 恢復現場 銷燬臨時的記憶體DC 例項 ( showbmp.cpp) 進一步的改

基於VC6.0 MFC的簡單串列埠通訊軟體程式設計總結

想想上回玩VC是幾年前搞畢設時的事了,這回編這個串列埠軟體也花了好幾天時間,做個小結積累一下吧: (一)基於對話方塊程式設計基本步驟: 1.新建基於對話方塊的工程; 2.拖曳所需的基本控制元件,構成介面; 3.使用類嚮導(CLASS WIZARD)建立與基本控制元件對應的成員

C語言操作MYSQL------基於VC6.0 & VS2010

相信大家在ubuntu下用c操作mysql已經相當的熟悉,對比在windows下其實操作起來也不復雜,這個教程是為了整理在windows下用c操作mysql的過程,平臺基於VC6.0,相信VS2010等一樣可以照此移植。 1、開啟VC6.0,建立Win32的控制檯應用程式,

如何用VC6.0寫第一個C語言程式

首先我們開啟我們安裝好的VC6.0. 選擇”檔案—->新建”. 在新建視窗中,選擇“專案”中的“WIN32 Console Application(控制檯應用程式)”,在“工程名稱”

基於OpenCV3.0的車牌識別系統設計--車牌提取

寫在前面的話 上一篇開篇博文寫好之後找女朋友看了一下,希望她提一點建設性建議。結果她很委婉的告訴我,寫的還行就是太表面了,告訴我要注意細節的描述與具體的實現過程與原理等等。其實我只是想騙她看一下增加一下點選量,順便知道我寫的部落格新手能不能看懂而已。結果她告訴我,她那麼聰明當然能看懂,別人就

基於OpenCV3.0的車牌識別系統設計--系統綜述

寫在前面的話        車牌識別是影象處理技術的實際生活中一個非常重要的應用場景,目前車牌識別系統已經非常完善,識別準確率高達99%以上。作為學生,在學習影象處理時,自己搭建車牌識別系統是非常有價值的,作為入門專案有助於快速入門。並且在識

【C語言】實現對一個8bit資料unsigned char 型別的指定位例如第n位的置0或者置1操作,並保持其他位不變

請編碼實現以下功能的函式 功能:實現對一個8bit資料(unsigned char 型別)的指定位(例如第n位)的置0或者置1操作,並保持其他位不變。 函式原型:void bit_set(unsigned char *p_data,unsigned char position,int flag)

selenium學習之--從0開始搭建一個測試框架總章

目錄 思考:我們需要一個什麼樣的框架 既然要搭一個框架,我們首先得弄明白我們需要一個什麼樣的框架,這個框架要支援什麼功能? 框架主要的作用就是幫助我們編寫更簡單並且好維護的用例。我們需要把所有除測試用例以外的東西抽象出來作為框架的部分。 那麼,額外的東西是

0~5年一個Java程式設計師從入到大牛的晉升之路

在程式界流行著一種預設的說法叫“黃金5年”,也就是一個程式設計師從入職的時候算起,前五年的選擇直接影響著整個職業生涯中的職業發展方向和薪資走向,如何走好這5年,徹底從一個剛入行的菜鳥蛻變成可以以不變應萬變的職業大牛,這是一個涉及到自身專業知識儲備和選擇的大難題,那麼,這五

【c語言】實現對一個8bit資料unsigned char 型別的指定位例如第n位0或者置1操作,並保持其他位不變

// 實現對一個8bit資料(unsigned char 型別)的指定位(例如第n位)置0或者置1操作,並保持其他位不變 #include <stdio.h> void bit_set(unsigned char *p_data, unsigned char

【分享】分享一個基於SSH實現的簡單學生選課系統附源碼

download 3.2 cor 點擊 小菜 我們 重新 模式窗口 額外 首先聲明:本小項目是因老師而做,主要為了完成老師項目要求,當然也添加了許多老師沒有要求的功能,本項目代碼非常簡單,分享出來時為了和我一樣的小菜鳥共同學習一下,只適合初學者拿來學習,大牛可直接繞過。

css3的一個小demo箭頭hover變化

rotate osi ping align pos ref block translate -m 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta char

基於Axis1.4的webservice接口開發代碼開發

-c oba config soap blog schema vid hand lock 基於Axis1.4的webservice接口開發(代碼開發) 一、開發環境:   我的開發環境是MyEclipse 2015+Apache-Tomcat-8.0.21。 二、代碼開發:

對於同一套應用程序如何發布一個體驗版有部分功能完整版有完整功能

service() () ogr com 完整 fine adk testin generic 最近項目中,先做一個版本給用戶(普通用戶作為體驗使用)。之後再有一個完整功能版。 #define OFFLINE using System; using System.

Android Studio 2.0 正式版公布啦 首次中文翻譯

2.0 play user attribute ast 調試 iou osi watermark Android Studio 2.0 公布了,添加了一些新特性: 1. 更加完好的 Instant Run 2. 更快的 A

【Java TCP/IP Socket】基於線程池的TCP服務器含代碼

init 成對 之前 .get font ack 字符串 fonts exceptio 了解線程池 在http://blog.csdn.net/ns_code/article/details/14105457(讀書筆記一:TCP Socket)這篇博文中,服務器