亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

利用C語言繪制一個正方體

 更新時間:2023年01月06日 08:24:33   作者:編程小魚六六六  
這篇文章主要為大家詳細(xì)介紹了如何利用C語言繪制一個正方體,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)和借鑒價值,感興趣的小伙伴可以學(xué)習(xí)一下

程序截圖

操作方法

鼠標(biāo)拖動。左鍵拖動及滾輪能看到不同角度下正方體的形狀,右鍵拖動能將最近的正方體頂點(diǎn)挪到這個投影面的相應(yīng)位置。

按鍵控制。wasd 控制投影面旋轉(zhuǎn),ws 關(guān)于 x 軸旋轉(zhuǎn),ad 關(guān)于 y 軸旋轉(zhuǎn)。

個人思路

首先投影面的確立需要兩個量,一個 x 軸方向的單位向量,一個 y 軸方向的單位向量,求原點(diǎn)與三維空間中的點(diǎn)的連線到這兩個單位向量的投影就能得到三維空間中的點(diǎn)在二維投影面中的坐標(biāo)。記 x 軸方向單位向量為 X,y 軸方向單位向量為 Y,X 與 Y 互相垂直,模都為 1。

正方體的八個頂點(diǎn)位置隨意,X,Y 兩個單位向量只需是互相垂直的非零向量即可。

鼠標(biāo)橫向拖動時,X 關(guān)于 Y 旋轉(zhuǎn),這是怎么做到的呢。要做到這一點(diǎn),就需要一個新的向量,也就是投影面的法向量,投影面的法向量可以根據(jù)兩向量叉乘得到。叉乘的推法用的是線性代數(shù)的方法,但是不好理解,我用我的方法推出來,希望能方便理解。

設(shè)投影面法向量為 Z(x2, y2, z2),X(x0, y0, z0) 和 Y(x1, y1, z1) 與 Z 的點(diǎn)乘為 0,這就能列出兩個式子:

① x0x2+y0y2+z0z2 = 0

② x1x2+y1y2+z1z2 = 0

將①式轉(zhuǎn)化為以 x2 和 y2 表示的 z2 得

③ z2 = - (x0x2 + y0y2) / z0

將②式和③式結(jié)合轉(zhuǎn)化為以 x2 表示的 y2 得

④ y2 = (x0z1 - x1z0) / (y1z0 - y0z1) * x2

④式代回③式得

⑤ z2 = (x1y0 - x0y1) / (y1z0 - y0z1) * x2 (推這一步時負(fù)號別忘了看)

也就是 Z = [x2, (x0z1 - x1z0) / (y1z0 - y0z1) * x2, (x1y0 - x0y1) / (y1z0 - y0z1) * x2]

仔細(xì)觀察 Z 只有一個變量 x2,不妨先放大(y1z0 - y0z1)倍,得到

Z = [(y1z0 - y0z1) * x2, (x0z1 - x1z0) * x2, (x1y0 - x0y1) * x2]

把 x2 提取出來,Z 就是 Z = x2 * [(y1z0 - y0z1), (x0z1 - x1z0), (x1y0 - x0y1)]

令 x2 = 1,Z[(y1z0 - y0z1), (x0z1 - x1z0), (x1y0 - x0y1)] 就是投影面的法向量。到這一步還沒有結(jié)束,因?yàn)榇怪庇谝粋€面的法向量有兩個,一個符合右手坐標(biāo)系,一個符合左手坐標(biāo)系,將 X(1, 0, 0),Y(0, 1, 0) 代入得 Z(0, 0, -1),所以這個 Z 是符合左手坐標(biāo)系的投影面法向量,要轉(zhuǎn)換成右手坐標(biāo)系只需乘個 -1 就行,也就是 Z 最終為 (y0z1 - y1z0, x1z0 - x0z1, x0y1 - x1y0)。

由于 X,Y 都是單位向量,這個 Z 還是投影面的單位法向量。

Z 求出來了,X 關(guān)于 Y 旋轉(zhuǎn)可以看做 X 在 XOZ 平面上旋轉(zhuǎn),問題轉(zhuǎn)化成了求平面中某個向量轉(zhuǎn)過θ度后的向量,如下圖,將 X 看做下圖中的紅色向量,Z 看做下圖中的綠色向量,虛線為向量旋轉(zhuǎn)后θ度后的向量,可以發(fā)現(xiàn) cos(θ)X - sin(θ)Z,就能求出 X 順時針轉(zhuǎn)動θ度后的向量,而 cos(θ)Z + sin(θ)X 就能求出 Z 順時針轉(zhuǎn)動θ度后的向量。

其它的旋轉(zhuǎn)方式皆可以此類推。

代碼實(shí)現(xiàn)

TCW_GUI.h:

#pragma once
#include<graphics.h>
#include<string>
#include<list>
#include<functional>
#define TCW_GUI_BUTTON_MYSELF 0
 
 
namespace TCW_GUI
{
    enum class State
    {
        general = 0,
        touch = 1,
        press = 2,
        release = 3,
        forbidden = 4
    };
 
    class Vec2
    {
    public:
        double x, y;
        Vec2() :x(0), y(0) {}
        Vec2(double xx, double yy) :x(xx), y(yy) {};
        Vec2 operator+(Vec2 num)
        {
            return Vec2(x + num.x, y + num.y);
        }
        Vec2 operator-(Vec2 num)
        {
            return Vec2(x - num.x, y - num.y);
        }
        Vec2 operator/(double num)
        {
            return Vec2(x / num, y / num);
        }
        Vec2 operator*(double num)
        {
            return Vec2(x * num, y * num);
        }
    };
 
    class Rect
    {
    public:
        Rect() :size(), position() {}
        Rect(Vec2 position, Vec2 size) :size(size), position(position) {}
        Vec2 size;
        Vec2 position;
        bool isInRect(Vec2 point)
        {
            Vec2 left_top = position - size / 2.0;
            Vec2 right_buttom = position + size / 2.0;
            if (point.x >= left_top.x && point.y >= left_top.y &&
                point.x <= right_buttom.x && point.y <= right_buttom.y)return true;
            return false;
        }
    };
 
    class Button
    {
    private:
        double textsize = 20;
        double textareasize = 0.9;
        Vec2 defaultsize = Vec2(textwidth(L"...") / textareasize, textheight(L"...") / textareasize);
        Vec2 defaulttext = Vec2(textwidth(L"..."), textheight(L"..."));
        State nowstate = State::general;
        void DrawButton_General();
        void DrawButton_Touch();
        void DrawButton_Press();
        void DrawButton_Forbidden();
        bool isPress = false;
    public:
        Button() :boundingbox(), buttontext() {}
        Button(Rect boundingbox, std::wstring buttontext, std::function<int(void*)> releaseFunc, void* releaseParam) :
            boundingbox(boundingbox), buttontext(buttontext), releaseFunc(releaseFunc), releaseParam(releaseParam) {}
        std::wstring buttontext;
        Rect boundingbox;
        std::function<int(void*)> releaseFunc = nullptr;
        void* releaseParam = nullptr;
        void DrawButton();
        void receiver(ExMessage* msg);
        void ForbidButton() { this->nowstate = State::forbidden; }    // 禁用按鈕
        void RefreshButton() { this->nowstate = State::general; }    // 恢復(fù)按鈕
        void SetTextSize(double size)
        {
            textsize = size;
            defaultsize = Vec2(textsize * 1.5 / textareasize, textsize / textareasize);
            defaulttext = Vec2(textsize * 1.5, textsize);
        }
        void SetTextAreaSize(double size)
        {
            textareasize = size;
            defaultsize = Vec2(textsize * 1.5 / textareasize, textsize / textareasize);
            defaulttext = Vec2(textsize * 1.5, textsize);
        }
    };
 
    class ButtonManager
    {
        std::list<Button> buttonlist;
    public:
        Button* AddButton(Button button);
        void ReceiveMessage(ExMessage* msg);
        void DrawButton();
    };
 
    void Rectangle_TCW(Vec2 left_top, Vec2 right_buttom)
    {
        rectangle(left_top.x, left_top.y, right_buttom.x, right_buttom.y);
    }
 
    void Fillrectangle_TCW(Vec2 left_top, Vec2 right_buttom)
    {
        fillrectangle(left_top.x, left_top.y, right_buttom.x, right_buttom.y);
    }
 
    void Outtextxy_TCW(Vec2 position, const WCHAR* str)
    {
        outtextxy(position.x, position.y, str);
    }
 
    void Button::DrawButton_General()
    {
        LOGFONT log;
        COLORREF textcol;
        COLORREF linecol;
        COLORREF fillcol;
        int bkmode;
        gettextstyle(&log);
        bkmode = getbkmode();
        textcol = gettextcolor();
        linecol = getlinecolor();
        fillcol = getfillcolor();
 
        settextstyle(textsize, 0, TEXT("微軟雅黑"));
        settextcolor(BLACK);
        setbkmode(TRANSPARENT);
        setlinecolor(BLACK);
        setfillcolor(WHITE);
        Vec2 size_button = Vec2(this->boundingbox.size * textareasize);
        Vec2 size_text = Vec2(textwidth(this->buttontext.c_str()), textsize);
 
        if (boundingbox.size.x > defaultsize.x && boundingbox.size.y > defaultsize.y)
        {
            Rectangle_TCW(this->boundingbox.position - this->boundingbox.size / 2.0,
                this->boundingbox.position + this->boundingbox.size / 2.0);
            Fillrectangle_TCW(this->boundingbox.position - this->boundingbox.size / 2.0,
                this->boundingbox.position + this->boundingbox.size / 2.0);
            if (size_button.x >= size_text.x && size_button.y >= size_text.y)
            {
                Outtextxy_TCW(this->boundingbox.position - size_text / 2.0, buttontext.c_str());
            }
            else
            {
                int wordnum = size_button.x / textwidth(buttontext.c_str()) * buttontext.size() - 2;
                std::wstring realstr = buttontext.substr(0, wordnum);
                realstr += L"...";
                size_text = Vec2(textwidth(realstr.c_str()), textsize);
                Outtextxy_TCW(this->boundingbox.position - size_text / 2.0, realstr.c_str());
            }
        }
        else
        {
            Rectangle_TCW(this->boundingbox.position - this->defaultsize / 2.0,
                this->boundingbox.position + this->defaultsize / 2.0);
            Fillrectangle_TCW(this->boundingbox.position - this->defaultsize / 2.0,
                this->boundingbox.position + this->defaultsize / 2.0);
            if (defaulttext.x >= size_text.x && defaulttext.y >= size_text.y)
                Outtextxy_TCW(this->boundingbox.position - size_text / 2.0, buttontext.c_str());
            else Outtextxy_TCW(this->boundingbox.position - defaulttext / 2.0, TEXT("..."));
        }
 
        settextstyle(&log);
        settextcolor(textcol);
        setbkmode(bkmode);
        setlinecolor(linecol);
        setfillcolor(fillcol);
    }
 
    void Button::DrawButton_Touch()
    {
        LOGFONT log;
        COLORREF textcol;
        COLORREF linecol;
        COLORREF fillcol;
        int bkmode;
        gettextstyle(&log);
        bkmode = getbkmode();
        textcol = gettextcolor();
        linecol = getlinecolor();
        fillcol = getfillcolor();
 
        settextstyle(textsize, 0, TEXT("微軟雅黑"));
        settextcolor(BLACK);
        setbkmode(TRANSPARENT);
        setlinecolor(BLACK);
        setfillcolor(RGB(240, 240, 240));
        Vec2 size_button = Vec2(this->boundingbox.size * textareasize);
        Vec2 size_text = Vec2(textwidth(this->buttontext.c_str()), textsize);
 
        if (boundingbox.size.x > defaultsize.x && boundingbox.size.y > defaultsize.y)
        {
            Rectangle_TCW(this->boundingbox.position - this->boundingbox.size / 2.0,
                this->boundingbox.position + this->boundingbox.size / 2.0);
            Fillrectangle_TCW(this->boundingbox.position - this->boundingbox.size / 2.0,
                this->boundingbox.position + this->boundingbox.size / 2.0);
            if (size_button.x >= size_text.x && size_button.y >= size_text.y)
            {
                Outtextxy_TCW(this->boundingbox.position - size_text / 2.0, buttontext.c_str());
            }
            else
            {
                int wordnum = size_button.x / textwidth(buttontext.c_str()) * buttontext.size() - 2;
                std::wstring realstr = buttontext.substr(0, wordnum);
                realstr += L"...";
                size_text = Vec2(textwidth(realstr.c_str()), textsize);
                Outtextxy_TCW(this->boundingbox.position - size_text / 2.0, realstr.c_str());
            }
        }
        else
        {
            Rectangle_TCW(this->boundingbox.position - this->defaultsize / 2.0,
                this->boundingbox.position + this->defaultsize / 2.0);
            Fillrectangle_TCW(this->boundingbox.position - this->defaultsize / 2.0,
                this->boundingbox.position + this->defaultsize / 2.0);
            if (defaulttext.x >= size_text.x && defaulttext.y >= size_text.y)
                Outtextxy_TCW(this->boundingbox.position - size_text / 2.0, buttontext.c_str());
            else Outtextxy_TCW(this->boundingbox.position - defaulttext / 2.0, TEXT("..."));
        }
 
        settextstyle(&log);
        settextcolor(textcol);
        setbkmode(bkmode);
        setlinecolor(linecol);
        setfillcolor(fillcol);
    }
 
    void Button::DrawButton_Press()
    {
        LOGFONT log;
        COLORREF textcol;
        COLORREF linecol;
        COLORREF fillcol;
        int bkmode;
        gettextstyle(&log);
        bkmode = getbkmode();
        textcol = gettextcolor();
        linecol = getlinecolor();
        fillcol = getfillcolor();
 
        settextstyle(textsize, 0, TEXT("微軟雅黑"));    // 設(shè)置字體為寬高 20 的字,有一些字體的中文寬度為字母的兩倍
        settextcolor(BLACK);
        setbkmode(TRANSPARENT);
        setlinecolor(BLACK);
        setfillcolor(RGB(240, 240, 240));
        Vec2 size_button = Vec2(this->boundingbox.size * textareasize);
        Vec2 size_text = Vec2(textwidth(this->buttontext.c_str()), textsize);
 
        if (boundingbox.size.x > defaultsize.x && boundingbox.size.y > defaultsize.y)
        {
            Rectangle_TCW(this->boundingbox.position - this->boundingbox.size / 2.0,
                this->boundingbox.position + this->boundingbox.size / 2.0);
            Fillrectangle_TCW(this->boundingbox.position - this->boundingbox.size / 2.0,
                this->boundingbox.position + this->boundingbox.size / 2.0);
            if (size_button.x >= size_text.x && size_button.y >= size_text.y)
            {
                Outtextxy_TCW(this->boundingbox.position - size_text / 2.0 + Vec2(2, 2), buttontext.c_str());
            }
            else
            {
                int wordnum = size_button.x / textwidth(buttontext.c_str()) * buttontext.size() - 2;
                std::wstring realstr = buttontext.substr(0, wordnum);
                realstr += L"...";
                size_text = Vec2(textwidth(realstr.c_str()), textsize);
                Outtextxy_TCW(this->boundingbox.position - size_text / 2.0, realstr.c_str());
            }
        }
        else
        {
            Rectangle_TCW(this->boundingbox.position - this->defaultsize / 2.0,
                this->boundingbox.position + this->defaultsize / 2.0);
            Fillrectangle_TCW(this->boundingbox.position - this->defaultsize / 2.0,
                this->boundingbox.position + this->defaultsize / 2.0);
            if (defaulttext.x >= size_text.x && defaulttext.y >= size_text.y)
                Outtextxy_TCW(this->boundingbox.position - size_text / 2.0 + Vec2(2, 2), buttontext.c_str());
            else Outtextxy_TCW(this->boundingbox.position - defaulttext / 2.0 + Vec2(2, 2), TEXT("..."));
        }
 
        settextstyle(&log);
        settextcolor(textcol);
        setbkmode(bkmode);
        setlinecolor(linecol);
        setfillcolor(fillcol);
    }
    
    void Button::DrawButton_Forbidden()
    {
        LOGFONT log;
        COLORREF textcol;
        COLORREF linecol;
        COLORREF fillcol;
        int bkmode;
        gettextstyle(&log);
        bkmode = getbkmode();
        textcol = gettextcolor();
        linecol = getlinecolor();
        fillcol = getfillcolor();
 
        settextstyle(textsize, 0, TEXT("微軟雅黑"));
        settextcolor(RGB(128, 128, 128));
        setbkmode(TRANSPARENT);
        setlinecolor(BLACK);
        setfillcolor(WHITE);
        Vec2 size_button = Vec2(this->boundingbox.size * textareasize);
        Vec2 size_text = Vec2(textwidth(this->buttontext.c_str()), textsize);
 
        if (boundingbox.size.x > defaultsize.x && boundingbox.size.y > defaultsize.y)
        {
            Rectangle_TCW(this->boundingbox.position - this->boundingbox.size / 2.0,
                this->boundingbox.position + this->boundingbox.size / 2.0);
            Fillrectangle_TCW(this->boundingbox.position - this->boundingbox.size / 2.0,
                this->boundingbox.position + this->boundingbox.size / 2.0);
            if (size_button.x >= size_text.x && size_button.y >= size_text.y)
            {
                Outtextxy_TCW(this->boundingbox.position - size_text / 2.0, buttontext.c_str());
            }
            else
            {
                int wordnum = size_button.x / textwidth(buttontext.c_str()) * buttontext.size() - 2;
                std::wstring realstr = buttontext.substr(0, wordnum);
                realstr += L"...";
                size_text = Vec2(textwidth(realstr.c_str()), textsize);
                Outtextxy_TCW(this->boundingbox.position - size_text / 2.0, realstr.c_str());
            }
        }
        else
        {
            Rectangle_TCW(this->boundingbox.position - this->defaultsize / 2.0,
                this->boundingbox.position + this->defaultsize / 2.0);
            Fillrectangle_TCW(this->boundingbox.position - this->defaultsize / 2.0,
                this->boundingbox.position + this->defaultsize / 2.0);
            if (defaulttext.x >= size_text.x && defaulttext.y >= size_text.y)
                Outtextxy_TCW(this->boundingbox.position - size_text / 2.0, buttontext.c_str());
            else Outtextxy_TCW(this->boundingbox.position - defaulttext / 2.0, TEXT("..."));
        }
 
        settextstyle(&log);
        settextcolor(textcol);
        setbkmode(bkmode);
        setlinecolor(linecol);
        setfillcolor(fillcol);
    }
 
    void Button::DrawButton()
    {
        switch (this->nowstate)
        {
        case State::general:
            DrawButton_General();
            break;
        case State::touch:
            DrawButton_Touch();
            break;
        case State::press:
            DrawButton_Press();
            break;
        case State::release:
            DrawButton_Touch();
            if (releaseFunc != nullptr)
            {
                if (releaseParam == TCW_GUI_BUTTON_MYSELF)releaseFunc(this);
                else releaseFunc(releaseParam);
            }
            this->nowstate = State::touch;
            break;
        case State::forbidden:
            DrawButton_Forbidden();
            break;
        default:
            break;
        }
    }
 
    void Button::receiver(ExMessage* msg)
    {
        if (this->nowstate == State::forbidden)return;
        // 先 general 后 touch 再 press 一個 release 后重新 general
        if (!isPress && !this->boundingbox.isInRect(Vec2(msg->x, msg->y)))
        {
            this->nowstate = State::general;
        }
        else if (!isPress && this->boundingbox.isInRect(Vec2(msg->x, msg->y)))
        {
            if (!msg->lbutton)
                this->nowstate = State::touch;
            else if (this->nowstate == State::touch)
            {
                isPress = true;
                this->nowstate = State::press;
            }
        }
        else if (isPress && this->boundingbox.isInRect(Vec2(msg->x, msg->y)))
        {
            if (!msg->lbutton)
            {
                isPress = false;
                this->nowstate = State::release;
            }
            else this->nowstate = State::press;
        }
        else if (isPress && !this->boundingbox.isInRect(Vec2(msg->x, msg->y)))
        {
            if (!msg->lbutton)
            {
                isPress = false;
                this->nowstate = State::general;
            }
            else this->nowstate = State::press;
        }
    }
 
    Button* ButtonManager::AddButton(Button button)
    {
        this->buttonlist.push_back(button);
        return &buttonlist.back();
    }
 
    void ButtonManager::ReceiveMessage(ExMessage* msg)
    {
        for (Button& button : this->buttonlist)
        {
            button.receiver(msg);
        }
    }
 
    void ButtonManager::DrawButton()
    {
        for (Button& button : this->buttonlist)
        {
            button.DrawButton();
        }
    }
}

main.cpp:

 
// 程序:一個正方體
// 編譯環(huán)境:Visual Studio 2019,EasyX_20211109
// 
 
#include<math.h>
#include<conio.h>
#include"TCW_GUI.h"
#define WIDTH 640						// 窗口寬度
#define HEIGHT 480						// 窗口高度
#define PI 3.14159265					// π
#define SIDE (min(WIDTH, HEIGHT) / 4)	// 正方體邊長
#define GAMEPAD (SIDE / 2)				// 手柄,控制面旋轉(zhuǎn)幅度的量
#define DISPLAY 3						// 展示出來頂點(diǎn)的尺寸
#define ARROWS 3						// 箭頭尺寸
#define PIECE 360
double FocalLength = 6;					// 觀察點(diǎn)到投影面的距離
 
// 8 個頂點(diǎn)的顏色,用于分辨 8 個不同的點(diǎn)
COLORREF VertexColor[8] =
{
	RED, YELLOW, BLUE, GREEN, BROWN, MAGENTA, CYAN, WHITE
};
 
struct Vec2
{
	double x, y;
};
 
Vec2 operator*(Vec2 a, double num)
{
	return { a.x * num, a.y * num };
}
 
Vec2 operator+(Vec2 a, Vec2 b)
{
	return { a.x + b.x, a.y + b.y };
}
 
Vec2 operator-(Vec2 a, Vec2 b)
{
	return { a.x - b.x, a.y - b.y };
}
 
double operator*(Vec2 a, Vec2 b)
{
	return a.x * b.x + a.y * b.y;
}
 
Vec2 operator/(Vec2 a, double num)
{
	return { a.x / num, a.y / num };
}
 
// 三維向量,也可以表示一個坐標(biāo)
struct Vec3
{
	double x, y, z;
};
typedef struct Vec3;
 
// 求兩向量相減
Vec3 operator-(Vec3 a, Vec3 b)
{
	return { a.x - b.x, a.y - b.y, a.z - b.z };
}
 
// 求兩向量相加
Vec3 operator+(Vec3 a, Vec3 b)
{
	return { a.x + b.x, a.y + b.y, a.z + b.z };
}
 
// 得到兩向量點(diǎn)乘的值
double operator*(Vec3 a, Vec3 b)
{
	return a.x * b.x + a.y * b.y + a.z * b.z;
}
 
// 得到向量縮短 num 倍后的向量
Vec3 operator/(Vec3 a, long double num)
{
	Vec3 result;
	result.x = a.x / num;
	result.y = a.y / num;
	result.z = a.z / num;
	return result;
}
 
// 得到向量延長 num 倍后的向量
Vec3 operator*(Vec3 a, long double num)
{
	Vec3 result;
	result.x = a.x * num;
	result.y = a.y * num;
	result.z = a.z * num;
	return result;
}
 
// 得到一個向量的模長
double GetVec3Length(Vec3 vec)
{
	return sqrt(vec.x * vec.x + vec.y * vec.y + vec.z * vec.z);
}
 
// 得到向量 a 與向量 b 的夾角余弦值
double GetCosineOfTheAngle(Vec3 a, Vec3 b)
{
	return a * b / GetVec3Length(a) / GetVec3Length(b);
}
 
// 得到向量 A 在向量 B 上的投影
Vec3 GetProjectionAOntoB(Vec3 A, Vec3 B)
{
	double num = GetCosineOfTheAngle(A, B);				// 得到向量 A,B 的夾角余弦值
	double length = GetVec3Length(A) * num;					// 向量 A 的模長乘 num 為向量 A 在向量 B 上投影的模長
	Vec3 result = B * (abs(length) / GetVec3Length(B));	// 向量 B 延長 length 倍再縮短 B 的模長倍就是向量 A 在向量 B 上的投影
	// 如果 length 比 0 小說明 num 小于 0,也就是兩向量夾角大于 90 度,結(jié)果要變?yōu)橄喾聪蛄?
	if (length > 0)return result;
	return result * (-1.0);
}
 
// 根據(jù)投影面 x,y 軸正方向向量求出投影面法向量
Vec3 getVerticalAxis(Vec3 AuxiliaryVector[2])
{
	double x0 = AuxiliaryVector[0].x;
	double y0 = AuxiliaryVector[0].y;
	double z0 = AuxiliaryVector[0].z;
	double x1 = AuxiliaryVector[1].x;
	double y1 = AuxiliaryVector[1].y;
	double z1 = AuxiliaryVector[1].z;
	Vec3 result = { y0 * z1 - y1 * z0, x1 * z0 - x0 * z1, x0 * y1 - x1 * y0 };
	return result;
}
 
// 將三維的點(diǎn)的值轉(zhuǎn)換為在對應(yīng) xoy 面上的投影的坐標(biāo)
typedef Vec3 DoubleVec3[2];
Vec2 Transform3DTo2D(Vec3 vertex, DoubleVec3 AuxiliaryVector, bool isParallel)
{
	Vec2 result;
	Vec3 tempX = GetProjectionAOntoB(vertex, AuxiliaryVector[0]);	// 得到三維向量在 x 軸上的投影
	Vec3 tempY = GetProjectionAOntoB(vertex, AuxiliaryVector[1]);	// 得到三維向量在 y 軸上的投影
	result.x = GetVec3Length(tempX);								// 得到 tempX 的模長,模長就是結(jié)果的 x 值的絕對值
	result.y = GetVec3Length(tempY);								// 得到 tempY 的模長,模長就是結(jié)果的 y 值的絕對值
	if (tempX * AuxiliaryVector[0] < 0)result.x *= -1;				// 如果 tempX 向量與 x 軸正方向的向量夾角大于 90 度,也就是向量點(diǎn)乘為負(fù)數(shù),那么結(jié)果的 x 值為負(fù)數(shù)
	if (tempY * AuxiliaryVector[1] < 0)result.y *= -1;				// 如果 tempY 向量與 y 軸正方向的向量夾角大于 90 度,也就是向量點(diǎn)乘為負(fù)數(shù),那么結(jié)果的 y 值為負(fù)數(shù)
	if (isParallel)return result;
	Vec3 Vec_Z = getVerticalAxis(AuxiliaryVector) * SIDE * FocalLength;
	Vec3 target = vertex - Vec_Z;
	return result * (SIDE * FocalLength / GetVec3Length(GetProjectionAOntoB(target, Vec_Z)));
}
 
// 畫一個正方體
void drawCube(Vec3 Vertex[8], Vec3 AuxiliaryVector[2], Vec2 pericenter, bool isParallel)
{
	Vec2 Temp[8];
	for (int i = 0; i < 8; i++)
	{
		Vec2 temp = Transform3DTo2D(Vertex[i], AuxiliaryVector, isParallel);
		Temp[i] = temp;
		setfillcolor(VertexColor[i]);
		solidcircle(temp.x + pericenter.x, temp.y + pericenter.y, DISPLAY);
	}
	line(Temp[0].x + pericenter.x, Temp[0].y + pericenter.y, Temp[3].x + pericenter.x, Temp[3].y + pericenter.y);
	line(Temp[0].x + pericenter.x, Temp[0].y + pericenter.y, Temp[1].x + pericenter.x, Temp[1].y + pericenter.y);
	line(Temp[0].x + pericenter.x, Temp[0].y + pericenter.y, Temp[4].x + pericenter.x, Temp[4].y + pericenter.y);
	line(Temp[1].x + pericenter.x, Temp[1].y + pericenter.y, Temp[2].x + pericenter.x, Temp[2].y + pericenter.y);
	line(Temp[1].x + pericenter.x, Temp[1].y + pericenter.y, Temp[5].x + pericenter.x, Temp[5].y + pericenter.y);
	line(Temp[2].x + pericenter.x, Temp[2].y + pericenter.y, Temp[3].x + pericenter.x, Temp[3].y + pericenter.y);
	line(Temp[2].x + pericenter.x, Temp[2].y + pericenter.y, Temp[6].x + pericenter.x, Temp[6].y + pericenter.y);
	line(Temp[3].x + pericenter.x, Temp[3].y + pericenter.y, Temp[7].x + pericenter.x, Temp[7].y + pericenter.y);
	line(Temp[4].x + pericenter.x, Temp[4].y + pericenter.y, Temp[5].x + pericenter.x, Temp[5].y + pericenter.y);
	line(Temp[4].x + pericenter.x, Temp[4].y + pericenter.y, Temp[7].x + pericenter.x, Temp[7].y + pericenter.y);
	line(Temp[5].x + pericenter.x, Temp[5].y + pericenter.y, Temp[6].x + pericenter.x, Temp[6].y + pericenter.y);
	line(Temp[6].x + pericenter.x, Temp[6].y + pericenter.y, Temp[7].x + pericenter.x, Temp[7].y + pericenter.y);
	char arr[128];
	WCHAR ano[128];
	settextstyle(0, 0, _T("Consolas"));
	settextcolor(WHITE);
	sprintf_s(arr, "x:(%f, %f, %f)", AuxiliaryVector[0].x, AuxiliaryVector[0].y, AuxiliaryVector[0].z);
	MultiByteToWideChar(CP_ACP, 0, arr, -1, ano, 128);
	outtextxy(10, HEIGHT / 6 * 5, ano);
	sprintf_s(arr, "y:(%f, %f, %f)", AuxiliaryVector[1].x, AuxiliaryVector[1].y, AuxiliaryVector[1].z);
	MultiByteToWideChar(CP_ACP, 0, arr, -1, ano, 128);
	outtextxy(10, HEIGHT / 9 * 8, ano);
}
 
// 得到兩個點(diǎn)之間的距離(二維)
double getTwoPointDistance(Vec2 a, Vec2 b)
{
	return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
 
// 得到 8 個頂點(diǎn)中距離 point 這個二維點(diǎn)最近的點(diǎn),p 是判斷兩點(diǎn)間距離是否符合要求的
int getNearestIndex(Vec3 Vertex[8], Vec3 AuxiliaryVector[2], Vec2 point, bool isParallel, bool (*p)(double) = nullptr)
{
	int result = 0;
	double nearestDistance = getTwoPointDistance(Transform3DTo2D(Vertex[0], AuxiliaryVector, isParallel), point);
	for (int i = 1; i < 8; i++)
	{
		double temp = getTwoPointDistance(Transform3DTo2D(Vertex[i], AuxiliaryVector, isParallel), point);
		if (temp < nearestDistance)
		{
			result = i;
			nearestDistance = temp;
		}
	}
	if (p != nullptr && !p(nearestDistance))return -1;
	return result;
}
 
void Line(Vec2 begin, Vec2 end)
{
	line(begin.x, begin.y, end.x, end.y);
}
 
// grading 是粒度,一條線分為幾份,0.1 是 10 份
void progressiveLine(Vec3 begincol, Vec3 endcol, Vec2 started, Vec2 finaled, double grading = 0.1)
{
	Vec2 AddLine = (finaled - started) * grading;
	Vec3 AddCol = (endcol - begincol) * grading;
	Vec3 nowcol = begincol;
	for (int i = 0; i < 1 / grading; i++)
	{
		nowcol = nowcol + AddCol;
		setlinecolor(RGB(nowcol.x, nowcol.y, nowcol.z));
		Line(started + AddLine * i, started + AddLine * (i + 1));
	}
}
 
// 畫坐標(biāo)軸,pericenter 是中心點(diǎn),size 是一個單位長度的長度
void drawCoordinateAxis(Vec2 pericenter, double size)
{
	setlinestyle(PS_SOLID, 1);
	setlinecolor(WHITE);
	settextcolor(WHITE);
	settextstyle(20, 0, _T("Consolas"));
	double index_X = size * sqrt(3) / sqrt(5);
	double index_Y = size * sqrt(2) / sqrt(5);
	progressiveLine({ 0, 0, 0 }, { 255, 255, 255 }, pericenter + Vec2({ -index_X, -index_Y }),
		pericenter + Vec2({ index_X, index_Y }));
	line(pericenter.x + index_X - ARROWS, pericenter.y + index_Y, pericenter.x + index_X, pericenter.y + index_Y);
	line(pericenter.x + index_X, pericenter.y + index_Y - ARROWS, pericenter.x + index_X, pericenter.y + index_Y);
	outtextxy(pericenter.x + index_X, pericenter.y + index_Y, L"y");
 
	progressiveLine({ 0, 0, 0 }, { 255, 255, 255 }, pericenter + Vec2({ index_X, -index_Y }),
		pericenter + Vec2({ -index_X, +index_Y }));
	line(pericenter.x - index_X + ARROWS, pericenter.y + index_Y, pericenter.x - index_X, pericenter.y + index_Y);
	line(pericenter.x - index_X, pericenter.y + index_Y - ARROWS, pericenter.x - index_X, pericenter.y + index_Y);
	outtextxy(pericenter.x - index_X, pericenter.y + index_Y, L"x");
 
	progressiveLine({ 0, 0, 0 }, { 255, 255, 255 }, pericenter + Vec2({ 0, index_X }),
		pericenter + Vec2({ 0, -index_X }));
	line(pericenter.x + ARROWS, pericenter.y - index_X + ARROWS, pericenter.x, pericenter.y - index_X);
	line(pericenter.x - ARROWS, pericenter.y - index_X + ARROWS, pericenter.x, pericenter.y - index_X);
	outtextxy(pericenter.x, pericenter.y - index_X - 20, L"z");
}
 
// 畫出輔助向量
void drawAuxiliaryVector(Vec3 AuxiliaryVector[2], Vec2 pericenter, double size, bool isParallel)
{
	settextstyle(20, 0, _T("Consolas"));
	Vec3 Auxiliary[2] = { {-1, 1, 0}, {-1, -1, 1} };
	Auxiliary[0] = Auxiliary[0] / GetVec3Length(Auxiliary[0]);
	Auxiliary[1] = Auxiliary[1] / GetVec3Length(Auxiliary[1]);
	Vec2 temp[2];
	temp[0] = Transform3DTo2D(AuxiliaryVector[0] * size, Auxiliary, isParallel);	// x 軸
	temp[1] = Transform3DTo2D(AuxiliaryVector[1] * size, Auxiliary, isParallel);	// y 軸
	double Cos_XX = GetCosineOfTheAngle(getVerticalAxis(Auxiliary), AuxiliaryVector[0]);
	double Cos_YY = GetCosineOfTheAngle(getVerticalAxis(Auxiliary), AuxiliaryVector[1]);
	if (Cos_XX < 0.0 && Cos_YY < 0.0)
	{
		setlinestyle(PS_SOLID, 2);
		progressiveLine({ 127, 0, 0 }, { 127 + 127 * Cos_XX, 0, 0 }, pericenter,
			pericenter + Vec2({ temp[0].x, -temp[0].y }));
		progressiveLine({ 127, 0, 0 }, { 127 + 127 * Cos_YY, 0, 0 }, pericenter,
			pericenter + Vec2({ temp[1].x, -temp[1].y }));
		drawCoordinateAxis(pericenter, size);
	}
	else if (Cos_XX >= 0.0 && Cos_YY < 0.0)
	{
		setlinestyle(PS_SOLID, 2);
		progressiveLine({ 127, 0, 0 }, { 127 + 127 * Cos_YY, 0, 0 }, pericenter,
			pericenter + Vec2({ temp[1].x, -temp[1].y }));
		drawCoordinateAxis(pericenter, size);
		setlinestyle(PS_SOLID, 2);
		progressiveLine({ 127, 0, 0 }, { 127 + 127 * Cos_XX, 0, 0 }, pericenter,
			pericenter + Vec2({ temp[0].x, -temp[0].y }));
	}
	else if (Cos_XX < 0.0 && Cos_YY >= 0.0)
	{
		setlinestyle(PS_SOLID, 2);
		progressiveLine({ 127, 0, 0 }, { 127 + 127 * Cos_XX, 0, 0 }, pericenter,
			pericenter + Vec2({ temp[0].x, -temp[0].y }));
		drawCoordinateAxis(pericenter, size);
		setlinestyle(PS_SOLID, 2);
		progressiveLine({ 127, 0, 0 }, { 127 + 127 * Cos_YY, 0, 0 }, pericenter,
			pericenter + Vec2({ temp[1].x, -temp[1].y }));
	}
	else if (Cos_XX >= 0.0 && Cos_YY >= 0.0)
	{
		drawCoordinateAxis(pericenter, size);
		setlinestyle(PS_SOLID, 2);
		progressiveLine({ 127, 0, 0 }, { 127 + 127 * Cos_XX, 0, 0 }, pericenter,
			pericenter + Vec2({ temp[0].x, -temp[0].y }));
		progressiveLine({ 127, 0, 0 }, { 127 + 127 * Cos_YY, 0, 0 }, pericenter,
			pericenter + Vec2({ temp[1].x, -temp[1].y }));
	}
	settextcolor(RED);
	outtextxy(pericenter.x + temp[0].x, pericenter.y - temp[0].y, L"X");
	outtextxy(pericenter.x + temp[1].x, pericenter.y - temp[1].y, L"Y");
	setlinestyle(PS_SOLID, 1);
	setlinecolor(WHITE);
}
 
// x 軸固定在 xoy 平面上,旋轉(zhuǎn) x 軸和 z 軸就能看到這個三維物體的所有角度!!!
int main()
{
	bool isExit = false;
	initgraph(WIDTH, HEIGHT);
	BeginBatchDraw();
	Vec3 AuxiliaryVector[2] = { { sqrt(2) / 2.0, sqrt(2) / 2.0, 0 },
		{ -sqrt(3) / 3.0, sqrt(3) / 3, sqrt(3) / 3.0 } };	// 輔助向量,分別是 x 軸,y 軸的單位向量
 
	bool isParallel = false;
 
	TCW_GUI::Button* button_param[2];
 
	TCW_GUI::ButtonManager manager;
	TCW_GUI::Button* button_temp = manager.AddButton(TCW_GUI::Button(TCW_GUI::Rect(TCW_GUI::Vec2(WIDTH * 5 / 6.0, HEIGHT / 6.0),
		TCW_GUI::Vec2(WIDTH / 7.0, HEIGHT / 7.0)), L"透視投影",
		[&](void* param)
		{
			TCW_GUI::Button** button = (TCW_GUI::Button**)param;
			if (isParallel)
			{
				button[0]->buttontext = L"透視投影";
				button[1]->RefreshButton();
				isParallel = false;
			}
			else
			{
				button[0]->buttontext = L"平行投影";
				button[1]->ForbidButton();
				isParallel = true;
			}
			return 0;
		}, nullptr));
	button_temp->releaseParam = button_param;
	button_param[0] = button_temp;
 
	button_param[1] = manager.AddButton(TCW_GUI::Button(TCW_GUI::Rect(TCW_GUI::Vec2(WIDTH * 5 / 6.0, HEIGHT / 3.0),
		TCW_GUI::Vec2(WIDTH / 7.0, HEIGHT / 7.0)), L"透視距離",
		[&](void* param)
		{
			WCHAR arr[128];
			char ano[128];
			InputBox(arr, 128, L"請輸入透視距離(推薦 1~10, 可小數(shù))");
			WideCharToMultiByte(CP_UTF8, 0, arr, -1, ano, 128, NULL, FALSE);
			sscanf(ano, "%lf", &FocalLength);
			return 0;
		}, nullptr));
 
	manager.AddButton(TCW_GUI::Button(TCW_GUI::Rect(TCW_GUI::Vec2(WIDTH * 5 / 6.0, HEIGHT / 2.0),
		TCW_GUI::Vec2(WIDTH / 7.0, HEIGHT / 7.0)), L"結(jié)束程序",
		[](void* param)
		{
			bool* isExit = (bool*)param;
			*isExit = true;
			return 0;
		}, &isExit));
 
	Vec3 Vertex[8];										// 8 個頂點(diǎn)的坐標(biāo)
	// 初始化 8 個頂點(diǎn),這 8 個頂點(diǎn)是固定的,可以改變?yōu)槿我庾鴺?biāo)值,我們只是從不同的角度看這 8 個頂點(diǎn)
	Vertex[0] = { -GAMEPAD, -GAMEPAD, -GAMEPAD };
	Vertex[1] = { GAMEPAD, -GAMEPAD, -GAMEPAD };
	Vertex[2] = { GAMEPAD, GAMEPAD, -GAMEPAD };
	Vertex[3] = { -GAMEPAD, GAMEPAD, -GAMEPAD };
	Vertex[4] = { -GAMEPAD, -GAMEPAD, GAMEPAD };
	Vertex[5] = { GAMEPAD, -GAMEPAD, GAMEPAD };
	Vertex[6] = { GAMEPAD, GAMEPAD, GAMEPAD };
	Vertex[7] = { -GAMEPAD, GAMEPAD, GAMEPAD };
	ExMessage msg;							// 鼠標(biāo)信息
	bool ispress = false;					// 是否按下
	bool isLpress = false;					// 是否按下左鍵
	bool isRpress = false;					// 是否按下右鍵
	double originalX = 0, originalY = 0;		// 原來的坐標(biāo)
	int vertexIndex = 0;					// 右鍵點(diǎn)擊時要操作的頂點(diǎn)的坐標(biāo)
	while (!isExit)
	{
		while (peekmessage(&msg, EM_MOUSE))
		{
			if (!ispress && (msg.lbutton || msg.rbutton))
			{
				ispress = true;
				if (msg.lbutton)isLpress = true;										// 左鍵按下
				else if (msg.rbutton)													// 右鍵按下
				{
					isRpress = true;
					vertexIndex = getNearestIndex(Vertex, AuxiliaryVector, 				// 得到距離按下的位置最近的正方體頂點(diǎn)的下標(biāo)
						{ (double)msg.x - WIDTH / 2, (double)msg.y - HEIGHT / 2 }, isParallel,
						[](double num) {if (num < DISPLAY)return true; return false; });	// 這個 lambda 表達(dá)式是為了讓點(diǎn)到的地方距離最近的正方體頂點(diǎn)距離小于展示出來正方體頂點(diǎn)的尺寸才能生效
				}
				originalX = msg.x;
				originalY = msg.y;
			}
			else if (isLpress && msg.lbutton)
			{
				double DelFi = (msg.y - originalY) / 6 / GAMEPAD * PI;
				double DelTh = (msg.x - originalX) / GAMEPAD / 6 * PI;
				Vec3 tempVectorX = AuxiliaryVector[0];
				Vec3 tempVectorY = AuxiliaryVector[1];
				Vec3 tempVectorZ = getVerticalAxis(AuxiliaryVector);
 
				AuxiliaryVector[0] = tempVectorX * cos(DelTh) + tempVectorZ * sin(DelTh);	// 改變 x 軸向量
				tempVectorZ = tempVectorZ * cos(DelTh) - tempVectorX * sin(DelTh);
				AuxiliaryVector[1] = tempVectorY * cos(DelFi) + tempVectorZ * sin(DelFi);	// 改變 y 軸向量
				originalX = msg.x;
				originalY = msg.y;
			}
			else if (isRpress && msg.rbutton && vertexIndex != -1)
			{
				double lengthX = msg.x - originalX;			// 在投影面橫坐標(biāo)上移動的距離
				double lengthY = msg.y - originalY;			// 在投影面縱坐標(biāo)上移動的距離
				// 對于選中的頂點(diǎn),它變?yōu)樗陨淼南蛄考由贤队懊嫔系南蛄?
				Vertex[vertexIndex] =
					Vertex[vertexIndex] +
					AuxiliaryVector[0] * lengthX / GetVec3Length(AuxiliaryVector[0]) +
					AuxiliaryVector[1] * lengthY / GetVec3Length(AuxiliaryVector[1]);
				originalX = msg.x;
				originalY = msg.y;
			}
			else if (ispress && !msg.lbutton)
			{
				ispress = false;
				isLpress = false;
				isRpress = false;
			}
			else if (msg.wheel)
			{
				double DelTh = msg.wheel / 120.0 * PI / 60.0;	// 滾動 120 度旋轉(zhuǎn) 3 度
				Vec3 tempVectorX = AuxiliaryVector[0];
				Vec3 tempVectorY = AuxiliaryVector[1];
				Vec3 tempVectorZ = getVerticalAxis(AuxiliaryVector);
				AuxiliaryVector[0] = tempVectorX * cos(DelTh) + tempVectorY * sin(DelTh);	// 改變 x 軸向量
				AuxiliaryVector[1] = tempVectorY * cos(DelTh) - tempVectorX * sin(DelTh);	// 改變 y 軸向量
			}
		}
		// 用鼠標(biāo)不能進(jìn)行精密控制,在這里用 wasd 實(shí)現(xiàn)鍵盤控制
		if (_kbhit())
		{
			// 按一下移動 3 度
			double DelFi = 0, DelTh = 0;
			Vec3 tempVectorX = AuxiliaryVector[0];
			Vec3 tempVectorY = AuxiliaryVector[1];
			Vec3 tempVectorZ = getVerticalAxis(AuxiliaryVector);
			switch (_getch())
			{
			case 'w':DelFi -= PI / 60.0;	break;
			case 'a':DelTh += PI / 60.0;	break;
			case 's':DelFi += PI / 60.0;	break;
			case 'd':DelTh -= PI / 60.0;	break;
			default:
				break;
			}
			AuxiliaryVector[0] = tempVectorX * cos(DelTh) + tempVectorZ * sin(DelTh);	// 改變 x 軸向量
			tempVectorZ = tempVectorZ * cos(DelTh) - tempVectorZ * sin(DelTh);
			AuxiliaryVector[1] = tempVectorY * cos(DelFi) + tempVectorZ * sin(DelFi);	// 改變 y 軸向量
		}
		cleardevice();
		drawCube(Vertex, AuxiliaryVector, { WIDTH / 2.0, HEIGHT / 2.0 }, isParallel);
		drawAuxiliaryVector(AuxiliaryVector, { WIDTH / 6 * 5, HEIGHT / 6 * 5 }, min(WIDTH, HEIGHT) / 9,
			isParallel);
		manager.ReceiveMessage(&msg);
		manager.DrawButton();
		FlushBatchDraw();
	}
	closegraph();
	return 0;
}

到此這篇關(guān)于利用C語言繪制一個正方體的文章就介紹到這了,更多相關(guān)C語言繪制正方體內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 深入解析C++ STL中的常用容器

    深入解析C++ STL中的常用容器

    這里我們不涉及容器的基本操作之類,只是要討論一下各個容器其各自的特點(diǎn)。STL中的常用容器包括:順序性容器(vector、deque、list)、關(guān)聯(lián)容器(map、set)、容器適配器(queue、stac)
    2013-09-09
  • C語言實(shí)現(xiàn)3*3數(shù)組對角線之和示例

    C語言實(shí)現(xiàn)3*3數(shù)組對角線之和示例

    今天小編就為大家分享一篇C語言實(shí)現(xiàn)3*3數(shù)組對角線之和示例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-12-12
  • 淺析C++中cout的運(yùn)行機(jī)制

    淺析C++中cout的運(yùn)行機(jī)制

    關(guān)于C++中cout的使用,相信大家再熟悉不過了,然而對于cout是如何輸出的?輸出的機(jī)制是啥,需要進(jìn)一步的了解。本章娓娓道來。前幾天在網(wǎng)上看到這么一個題目
    2013-10-10
  • Qt6.0開發(fā)環(huán)境搭建步驟(圖文)

    Qt6.0開發(fā)環(huán)境搭建步驟(圖文)

    這篇文章主要介紹了Qt6.0開發(fā)環(huán)境搭建步驟(圖文),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • 深入解析C++中類的多重繼承

    深入解析C++中類的多重繼承

    這篇文章主要介紹了深入解析C++中類的多重繼承,包括多重繼承相關(guān)的二義性問題,需要的朋友可以參考下
    2015-09-09
  • C/C++經(jīng)典實(shí)例之模擬計算器示例代碼

    C/C++經(jīng)典實(shí)例之模擬計算器示例代碼

    最近在看到的一個需求,本以為比較簡單,但花了不少時間,所以下面這篇文章主要給大家介紹了關(guān)于C/C++經(jīng)典實(shí)例之模擬計算器的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-10-10
  • C++模板 index_sequence使用示例詳解

    C++模板 index_sequence使用示例詳解

    這篇文章主要為大家介紹了C++模板 index_sequence使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • 數(shù)據(jù)結(jié)構(gòu)之?dāng)?shù)組Array實(shí)例詳解

    數(shù)據(jù)結(jié)構(gòu)之?dāng)?shù)組Array實(shí)例詳解

    這篇文章主要介紹了數(shù)據(jù)結(jié)構(gòu)之?dāng)?shù)組Array實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • C++求解二叉樹的下一個結(jié)點(diǎn)問題

    C++求解二叉樹的下一個結(jié)點(diǎn)問題

    本文將通過C++求解以下問題:給定一個二叉樹其中的一個結(jié)點(diǎn),請找出中序遍歷順序的下一個結(jié)點(diǎn)并且返回。文中示例代碼講解詳細(xì),感興趣的可以了解一下
    2022-04-04
  • C語言?柔性數(shù)組的使用詳解

    C語言?柔性數(shù)組的使用詳解

    柔性數(shù)組(Flexible?Array)是引入的一個新特性,它允許你在定義結(jié)構(gòu)體時創(chuàng)建一個空數(shù)組,而這個數(shù)組的大小可以在程序運(yùn)行的過程中根據(jù)你的需求進(jìn)行更改特別注意的一點(diǎn)是:這個空數(shù)組必須聲明為結(jié)構(gòu)體的最后一個成員,并且還要求這樣的結(jié)構(gòu)體至少包含一個其他類型的成員
    2022-03-03

最新評論