日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

边表法

發(fā)布時(shí)間:2023/12/20 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 边表法 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

邊表法是用來繪制填充一個(gè)面的,邊表法的關(guān)鍵是邊表和連接邊表的掃描線。

對(duì)于邊的描述利用邊表數(shù)據(jù)結(jié)構(gòu),包含邊與掃描線的交點(diǎn)x坐標(biāo),邊的最大y坐標(biāo),這樣可以知道邊加入到哪些掃描線上,便還有一個(gè)指針來記錄掃描線上其它邊。

//邊數(shù)據(jù)結(jié)構(gòu) #pragma once #ifndef __CAETZ__ #define __CAETZ__ #include "pch.h" #include "CPoint3D.h" #include "RGB.h" class CAETZ { public:CAETZ() = default;CAETZ(const CPoint3D &start,const CPoint3D &end);~CAETZ() {} public:CPoint3D start3D; //起點(diǎn)CPoint3D end3D; //終點(diǎn)int x; //與掃描線相交的x坐標(biāo)int y; //掃描線值int ymax; //最大的y值double k; //斜率kint z; //z值CRGB rgb; //rgb值CAETZ* pNext; //指向下一個(gè)邊表的指針 }; //表數(shù)據(jù)結(jié)構(gòu) #pragma once #ifndef __CBUCKETZ__ #define __CBUCKETZ__#include "CAETZ.h" #include "pch.h" #include "CPoint3D.h" #include "RGB.h" class CBucketZ { public:CBucketZ() = default;CBucketZ(CPoint3D *pointList ,int pointNum);~CBucketZ() {CAETZ *tempPET = NULL;while (pET != NULL){tempPET = pET->pNext;delete pET;pET = tempPET;}};int getScanLine() const { return this->ScanLine; }; public:CAETZ* pET;//邊表指針CBucketZ* pNext;//桶指針CPoint3D* point3DList;//其中xy是屏幕坐標(biāo)系的位置,z是相機(jī)坐標(biāo)系下的距離int pointNum;int ScanLine;//掃描線 private:void creatCBucketZ();//創(chuàng)建掃描線void creatCAETZ();//創(chuàng)建邊表void pETaddNext(CBucketZ* currentCBucket,CAETZ *nextCAET);//將邊表鏈接到掃描線的合適位置}; void CBucketZ::creatCBucketZ() {//計(jì)算當(dāng)前面所存在的掃描線范圍int yMin = (int) point3DList[0].y;int yMax = (int) point3DList[0].y;for (int i = 1; i < this->pointNum; i++){if (yMin > (int)point3DList[i].y)yMin = (int)point3DList[i].y;if(yMax < (int)point3DList[i].y)yMax = (int)point3DList[i].y;}//初始化第一個(gè)桶(掃描線)this->ScanLine = yMin;this->pET = NULL;this->pNext = NULL;//把后面所有需要的掃描線初始化(桶)CBucketZ* currentCBucket = this;for (int j = yMin + 1; j <= yMax; j++){CBucketZ* tempNext = new CBucketZ();tempNext->ScanLine = j;tempNext->pET = NULL;tempNext->pNext = NULL;currentCBucket->pNext = tempNext;//把新的掃描線放到上一條掃描線的pNextcurrentCBucket = tempNext;//將currentCBucket 指向新添加的指針} }void CBucketZ::creatCAETZ() {for (int i = 0; i < this->pointNum; i++){int j = (i + 1) % this->pointNum;//根據(jù)兩點(diǎn)創(chuàng)建一條邊表if ((int) point3DList[i].y != (int)point3DList[j].y)//與掃描線平行的線不需要加入到桶中{CAETZ* pETCAETZ = new CAETZ(point3DList[i], point3DList[j]);CAETZ* pETCAETZ2 = pETCAETZ;//將新創(chuàng)建的邊表添加到第一個(gè)桶中(第一條掃描線中)CBucketZ* currentCBucket = this;while (currentCBucket->getScanLine() != (int) pETCAETZ->y)//根據(jù)y值找到合適的掃描線currentCBucket = currentCBucket->pNext;//調(diào)用pETaddNext函數(shù)由x從小到大插入邊表currentCBucket->pETaddNext(currentCBucket, pETCAETZ);//將邊表加入到其他掃描線中for (int k = pETCAETZ2->y + 1; k < pETCAETZ2->ymax; k++)//下閉上開{int x = (int) pETCAETZ2->start3D.x + (k - pETCAETZ2->start3D.y) * pETCAETZ2->k;int z = (int)(pETCAETZ2->end3D.z - pETCAETZ2->start3D.z) * (k - pETCAETZ2->start3D.y) / (pETCAETZ2->end3D.y - pETCAETZ2->start3D.y) + pETCAETZ2->start3D.z;double r = (k - pETCAETZ2->start3D.y) / (pETCAETZ2->end3D.y - pETCAETZ2->start3D.y);CRGB newRgb = (pETCAETZ2->end3D.rgb * r + (1 - r) * pETCAETZ2->start3D.rgb);CPoint3D newStart3D(x, k, z,newRgb);CAETZ* newpETCAETZ = new CAETZ(newStart3D, pETCAETZ2->end3D);currentCBucket = currentCBucket->pNext;//調(diào)用pETaddNext函數(shù)由x從小到大插入邊表this->pETaddNext(currentCBucket, newpETCAETZ);}}}}void CBucketZ::pETaddNext(CBucketZ* currentCBucket, CAETZ* nextCAET) {int a = 0; //test***************************************************************CAETZ* currentpET = currentCBucket->pET;if (currentpET == NULL)//還沒有鏈接任何邊表{currentCBucket->pET = nextCAET;a = 1;}else {CAETZ* tempAET = NULL;while ((currentpET != NULL) && (currentpET->x) < (nextCAET->x)){tempAET = currentpET;currentpET = currentpET->pNext;}//存在鏈表頭if (tempAET == NULL){CAETZ* headpET = currentCBucket->pET;nextCAET->pNext = headpET;currentCBucket->pET = nextCAET;a = 1;//*********************}//存在鏈表尾else if (currentpET == NULL){tempAET->pNext = nextCAET;a = 1;//*****************************}//存在鏈表中間else{nextCAET->pNext = currentpET;tempAET->pNext = nextCAET;a = 1;//*******************************}} } #endif // !__CBUCKETZ__ #endif // ! __CAETZ__

總結(jié)

以上是生活随笔為你收集整理的边表法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。