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

歡迎訪問(wèn) 生活随笔!

生活随笔

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

编程问答

图形处理(十一)Stroke Parameterization

發(fā)布時(shí)間:2025/3/21 编程问答 49 豆豆
生活随笔 收集整理的這篇文章主要介紹了 图形处理(十一)Stroke Parameterization 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

轉(zhuǎn)眼已經(jīng)過(guò)去了好幾年,最近開(kāi)始寫技術(shù)博客,是為了回顧。《Stroke Parameterization》這篇paper是我人生寫的第一篇作者沒(méi)有提供代碼的文章,也是初次學(xué)會(huì)閱讀外文文獻(xiàn)的開(kāi)始。三年前菜鳥一只,連如何通過(guò)paper寫代碼都還不懂,然而沒(méi)想到這篇paper花了兩周的時(shí)間,竟然被我搞定了,有了信心,從此菜鳥開(kāi)始學(xué)習(xí)起飛……

這篇paper的作者也是一大牛,發(fā)了好多篇Siggraph的文章,所以自然這篇paper的質(zhì)量還是挺不錯(cuò)的。參數(shù)化算法的好壞一般是通過(guò)紋理貼圖的方法,進(jìn)行驗(yàn)證的。

一、相關(guān)理論


Stroke Parameterization顧名思義就是沿著曲線進(jìn)行參數(shù)化的意思,在我的另外一篇博文中《離散指數(shù)映射Decal》是以一個(gè)點(diǎn)為源點(diǎn),進(jìn)行參數(shù)化,參數(shù)化結(jié)果為一圓形參數(shù)域。然而在網(wǎng)格曲面上,可能有的時(shí)候我們并不緊緊是想要圓形Decal,而是希望沿著曲線進(jìn)行參數(shù)化,比如上面文字貼圖中,我們的圖片是一張長(zhǎng)方形圖片,這個(gè)時(shí)候如果用固定邊界的參數(shù)化方法,或者用離散指數(shù)Decal,它們的參數(shù)域一般都類似于圓形,用于上面的貼圖肯定不行。


或者又如上圖,我們給定的一張魚的圖片是矩形的,把魚圖片貼到那個(gè)魚缸上,這個(gè)時(shí)候,我們就要用到沿著曲線進(jìn)行參數(shù)化的方法了。

算法原理:


在網(wǎng)格曲面上,參數(shù)化無(wú)非就是要求解網(wǎng)格頂點(diǎn)的(u,v)坐標(biāo),如上圖所示,已知曲線C(tx),我們的目標(biāo)便是要求出曲線附近區(qū)域的每個(gè)頂點(diǎn)的(u,v)坐標(biāo),也就是我們要求出tx,dx,然后就可以得到二維的參數(shù)坐標(biāo):


dx表示網(wǎng)格頂點(diǎn)x到曲線的最短測(cè)地距離。


算法以Dijkstra算法為遍歷依據(jù),根據(jù)加權(quán)平均的方法,通過(guò)已Frozen的鄰接頂點(diǎn)更新計(jì)算未知的X點(diǎn)的相關(guān)信息。在參數(shù)化的過(guò)程中通過(guò)遍歷的方法,逐個(gè)計(jì)算頂點(diǎn)的局部坐標(biāo)系,參數(shù)化坐標(biāo)。

1、頂點(diǎn)x局部標(biāo)價(jià)的更新


頂點(diǎn)x的坐標(biāo)基底e1更新公式:


其中Nu(x)表示已經(jīng)被Dijkstra算法遍歷,且標(biāo)記為Fronzen的頂點(diǎn)(進(jìn)入隊(duì)列,并且又從隊(duì)列中刪除的點(diǎn),也就是已經(jīng)確定最短距離的頂點(diǎn)),且其為X點(diǎn)的一鄰接頂點(diǎn)。然后x點(diǎn)局部坐標(biāo)系的n軸為頂點(diǎn)的法矢,這個(gè)直接通過(guò)鄰接三角面片的加權(quán)平均就可以計(jì)算了。

然后,在已知n,e1軸后,我們可以直接用右手法則確定e2軸,也就是直接通過(guò)叉乘的方法確定e2:


2、參數(shù)化坐標(biāo)(u,v)更新

頂點(diǎn)x的參數(shù)化坐標(biāo)更新:


其中權(quán)重w(qi,x)的計(jì)算公式為:


ε是一個(gè)非常小的數(shù),以防分母為0,說(shuō)的簡(jiǎn)單一點(diǎn)就是以鄰接邊長(zhǎng)的倒數(shù)作為權(quán)重。

二、算法實(shí)現(xiàn)

后面我將結(jié)合我寫的代碼,進(jìn)行算法實(shí)現(xiàn)講解,因?yàn)檫@個(gè)算法是我還是菜鳥的時(shí)候?qū)懙拇a,然后后面也沒(méi)有經(jīng)過(guò)整理,只是把效果顯示出來(lái),得出結(jié)果,所以代碼很粗糙,將就一下。

Alogrithm:

1、初始化部分:

初始曲線s={pi}上的點(diǎn)pi相關(guān)參數(shù)初始化:

a、建立pi的局部標(biāo)價(jià)e1為曲線pi點(diǎn)處的切矢,n為頂?shù)追ㄊ?#xff0c;以此根據(jù)右手法則計(jì)算出e2

[cpp]?view plaincopy
  • vector<CVector3D>m_e1(m_SeedID.size());??
  • ???point?pt;??
  • for(int?i=0;i<m_SeedID.size();i++)??
  • {??
  • //計(jì)算種子點(diǎn)數(shù)組的e1基底:曲線的切向量作為e1??
  • ????if?(i==0)??
  • ????{??
  • ????????pt=Tmesh->vertices[m_SeedID[i+1]]-Tmesh->vertices[m_SeedID[i]];??
  • ????????m_nodes[m_SeedID[i]].m_e1=CVector3D(pt[0],pt[1],pt[2]);??
  • ????????m_nodes[m_SeedID[i]].m_e1.Normalize();??
  • ????}??
  • ????else?if?(i<m_SeedID.size()-1)??
  • ????{??
  • ????????pt=Tmesh->vertices[m_SeedID[i+1]]-Tmesh->vertices[m_SeedID[i-1]];??
  • ????????m_nodes[m_SeedID[i]].m_e1=CVector3D(pt[0],pt[1],pt[2]);??
  • ????????m_nodes[m_SeedID[i]].m_e1.Normalize();??
  • ????}??
  • ????else???
  • ????{??
  • ????????pt=Tmesh->vertices[m_SeedID[i]]-Tmesh->vertices[m_SeedID[i-1]];??
  • ????????m_nodes[m_SeedID[i]].m_e1=CVector3D(pt[0],pt[1],pt[2]);??
  • ????????m_nodes[m_SeedID[i]].m_e1.Normalize();??
  • ????}??
  • }??
  • m_SeedID為源曲線上點(diǎn)按順序存儲(chǔ)的索引。

    b、計(jì)算pi點(diǎn)的參數(shù)坐標(biāo)為:

    其中α(pi)為沿著曲線s,pi點(diǎn)的累積弧長(zhǎng),就是相當(dāng)于累積弧長(zhǎng)參數(shù)化。

    [cpp]?view plaincopy
  • vec?ab;??
  • vector<double>arccoordate(m_SeedID.size(),0.0);??
  • ??
  • for(int?i=0;i<m_SeedID.size()-1;i++)//弧長(zhǎng)參數(shù)化??
  • {??
  • ????ab=Tmesh->vertices[m_SeedID[i+1]]-Tmesh->vertices[m_SeedID[i]];???
  • ????sumlength+=len(ab);??
  • ????arccoordate[i+1]=sumlength;??
  • }??
  • c、pi點(diǎn)的測(cè)地距離設(shè)置為0(Dijkstra算法源點(diǎn)集設(shè)置)。

    [cpp]?view plaincopy
  • for(int?i=0;i<m_SeedID.size();i++)??
  • {??
  • ????m_nodes[m_SeedID[i]].m_UV.dx=arccoordate[i];//(u,v)坐標(biāo)設(shè)置??
  • ????m_nodes[m_SeedID[i]].m_UV.dy=0.0;??
  • ????m_nodes[m_SeedID[i]].m_VisitFlag=CDEMNode::Active;//標(biāo)記為活動(dòng),已加入隊(duì)列,但還未從隊(duì)列中刪除??
  • ????m_nodes[m_SeedID[i]].distance_from_source()=0.0;//距離設(shè)置為0??
  • ????m_nodes[m_SeedID[i]].m_GeodesicDistance=m_nodes[m_SeedID[i]].m_UV.GetLength();??
  • ????m_nodes[m_SeedID[i]].m_Normal=m_VertexNormals[m_SeedID[i]];??
  • ????m_nodes[m_SeedID[i]].m_e2=m_nodes[m_SeedID[i]].m_e1?*?m_nodes[m_SeedID[i]].m_Normal;//局部標(biāo)價(jià)初始化??
  • }??
  • 2、Dijkstra算法更新鄰域點(diǎn)

    根據(jù)前面所說(shuō)的計(jì)算方法進(jìn)行更新參數(shù)化坐標(biāo),及每個(gè)頂點(diǎn)的局部標(biāo)價(jià)。這一步主要就是用到公式2和公式3,然后在結(jié)合Dijkstra算法就OK了

    [cpp]?view plaincopy
  • void?CStrokeParameterization::DecalGeodesicVectors(TriMesh?*G1Mesh,double?r)?????
  • {??
  • ??
  • ????G1Mesh->need_normals();??
  • ????G1Mesh->need_neighbors();??
  • ????VertexNormals.clear();??
  • ????m_VertexNormals.clear();??
  • ????for?(int?i=0;i<G1Mesh->vertices.size();i++)??
  • ????{??
  • ????????vec?nor;??
  • ????????nor=G1Mesh->normals[i];??
  • ????????VertexNormals.push_back(nor);??
  • ????????nor=normalize(nor);??
  • ????????m_VertexNormals.push_back(CVector3D(nor[0],nor[1],nor[2]));??
  • ????}??
  • ??
  • ????//數(shù)據(jù)結(jié)構(gòu)轉(zhuǎn)化??
  • ????unsigned?vn,fn;??
  • ????vn=G1Mesh->vertices.size();???
  • ????fn=G1Mesh->faces.size();??
  • ????double?*pts;??
  • ????pts?=?new?double[vn*3];??
  • ????unsigned?*fs;??
  • ????fs?=?new?unsigned[fn*3];??
  • ??
  • ????for?(int?i=0;i<vn;i++)??
  • ????{??
  • ????????point?p=G1Mesh->vertices[i];??
  • ????????int?shift=i*3;??
  • ????????pts[shift]=p[0];??
  • ????????pts[shift+1]=p[1];??
  • ????????pts[shift+2]=p[2];??
  • ????}??
  • ????for?(int?i=0;i<fn;i++)??
  • ????{??
  • ????????int??shift=i*3;??
  • ????????fs[shift]=G1Mesh->faces[i][0];??
  • ????????fs[shift+1]=G1Mesh->faces[i][1];??
  • ????????fs[shift+2]=G1Mesh->faces[i][2];??
  • ????}??
  • ????Gmesh.from_TriMeshData(vn,pts,fn,fs);??
  • ????delete?[]pts;??
  • ????delete?[]fs;??
  • ????numOfVertices=G1Mesh->vertices.size();??
  • ????numOfFaces=G1Mesh->faces.size();??
  • ??
  • ??
  • ??
  • ????m_nodes.resize(numOfVertices);??
  • ????for(unsigned?i=0;?i<m_nodes.size();?++i)??
  • ????{??
  • ????????m_nodes[i].vertex()?=?&Gmesh.vertices()[i];??
  • ????????m_nodes[i].clear();??
  • ????????m_nodes[i].m_VertexID=i;??
  • ??????????
  • ????}??
  • ????std::set<DEMNode_pointer,?CDEMNode>??Queue0;???
  • ????Queue0.clear();??
  • ????InitializationSeed();??
  • ????for(int?i=0;i<m_CurveNeighbor.size();i++)??
  • ????{??
  • ??????Queue0.insert(&m_nodes[m_SeedCurve[i]]);??
  • ????}??
  • ????std::vector<double>?distances_between_nodes;??
  • ????std::vector<DEMNode_pointer>?neighbor_nodes;??
  • ????while(!Queue0.empty())??
  • ????{??
  • ????????DEMNode_pointer?min_node?=?*Queue0.begin();??
  • ????????Queue0.erase(Queue0.begin());??
  • ????????assert(min_node->distance_from_source()?<?GEODESIC_INF);??
  • ????????min_node->m_VisitFlag=CDEMNode::Frozen;??
  • ????????vector<int>::iterator?iter?=?find(m_CurveNeighbor.begin(),m_CurveNeighbor.end(),min_node->m_VertexID);??
  • ????????if?(iter==m_CurveNeighbor.end())??
  • ????????{??
  • ????????????min_node->m_e1=Average_e1(min_node->m_VertexID);??
  • ????????????min_node->m_Normal=m_VertexNormals[min_node->m_VertexID];??
  • ????????????min_node->m_e2=min_node->m_e1?*?min_node->m_Normal;??
  • ????????????min_node->m_UV=Average_GVector(min_node->m_VertexID);??
  • ????????????min_node->m_GeodesicDistance=min_node->m_UV.GetLength();??
  • ????????}??
  • ??????
  • ????????neighbor_nodes.clear();??
  • ????????distances_between_nodes.clear();??
  • ????????list_neighbor_from_node(min_node,?neighbor_nodes,?distances_between_nodes);??
  • ????????for(unsigned?i=0;?i<neighbor_nodes.size();?++i)????????
  • ????????{??
  • ????????????DEMNode_pointer?next_node?=?neighbor_nodes[i];??
  • ????????????if(next_node->distance_from_source()?>?min_node->distance_from_source()?+??
  • ????????????????distances_between_nodes[i])??
  • ????????????{??
  • ????????????????next_node->distance_from_source()?=?min_node->distance_from_source()?+??
  • ????????????????????distances_between_nodes[i];??
  • ????????????????next_node->previous()?=?min_node;??
  • ????????????}??
  • ????????}??
  • ??????
  • ????????int?neighbor_size_of_u=neighbor_size(min_node->vertex());??
  • ????????if((min_node->m_UV.dx<=(sumlength+r))&&(-r<(min_node->m_UV.dx))&&(abs(min_node->m_UV.dy)<=r))??
  • ????????{??
  • ????????????vertex_pointer?vertex_of_u=min_node->vertex();??
  • ????????????face_pointer?adjface_of_u;??
  • ????????????for?(int?i=0;i<vertex_of_u->adjacent_faces().size();i++)??
  • ????????????{??
  • ????????????????adjface_of_u=vertex_of_u->adjacent_faces()[i];??
  • ????????????????int?face_id=adjface_of_u->id();??
  • ????????????????G1Mesh->faces[face_id].beSelect=true;??
  • ????????????}??
  • ??
  • ??
  • ????????????for?(int?j=0;j<neighbor_size_of_u;j++)??
  • ????????????{??
  • ????????????????int?neighbors_of_u;??
  • ????????????????neighbors_of_u=neighbor_i(min_node->m_VertexID,j);??
  • ????????????????if?(m_nodes[neighbors_of_u].m_VisitFlag==CDEMNode::Inactive)??
  • ????????????????{??
  • ????????????????????Queue0.insert(&m_nodes[neighbors_of_u]);??
  • ????????????????????m_nodes[neighbors_of_u].m_VisitFlag=CDEMNode::Active;?????????????
  • ????????????????}??
  • ????????????}??
  • ????????}??
  • ??????
  • ????}//while??
  • ???DecalNormalization(r);??
  • }??
  • ??
  • int?CStrokeParameterization::neighbor_size(geodesic::vertex_pointer?u)??
  • {??
  • ????int?number;??
  • ????number=u->adjacent_edges().size();??
  • ????return?number;??
  • }??
  • int?CStrokeParameterization::neighbor_i(geodesic::vertex_pointer?u,int?i)??
  • {??
  • ????int?neighbor_id;??
  • ????edge_pointer?adjacent_e_u=u->adjacent_edges()[i];??
  • ????neighbor_id=adjacent_e_u->opposite_vertex(u)->id();??
  • ????return?neighbor_id;??
  • }??
  • int?CStrokeParameterization::neighbor_i(int?u,int?i)??
  • {??
  • ????int?neighbor_id;??
  • ????vertex_pointer?vertex_u=&Gmesh.vertices()[u];??
  • ????edge_pointer?adjacent_e_u=vertex_u->adjacent_edges()[i];??
  • ????vertex_pointer?adjacent_v_u=adjacent_e_u->opposite_vertex(vertex_u);??
  • ????neighbor_id=adjacent_v_u->id();??
  • ????return?neighbor_id;??
  • }??
  • vector<int>?CStrokeParameterization::Co_neighbor(int?u_id,int?v_id)??
  • {??
  • ????vector<int>?co_neighbor;??
  • ????co_neighbor.clear();??
  • ????vertex_pointer?u,v;??
  • ????u=&Gmesh.vertices()[u_id];??
  • ????v=&Gmesh.vertices()[v_id];????
  • ????for?(int?i=0;i<neighbor_size(u);i++)??
  • ????{??
  • ????????int?u_nei,v_nei;??
  • ????????u_nei=neighbor_i(u_id,i);??
  • ????????for(int?j=0;j<neighbor_size(v);j++)??
  • ????????{??
  • ????????????v_nei=neighbor_i(v_id,j);??
  • ????????????if?(u_nei==v_nei)??
  • ????????????{??
  • ????????????????co_neighbor.push_back(v_nei);??
  • ????????????}??
  • ????????}??
  • ??
  • ????}??
  • ??
  • ????return?co_neighbor;??
  • }??
  • //歸一化函數(shù)??
  • void?CStrokeParameterization::DecalNormalization(double?radius)??
  • {??
  • ????double?dScale=?1.0/?(3.0*radius);???????????????????
  • ????for?(int?i=0;i<m_nodes.size();i++)??
  • ????{??
  • ????????m_nodes[i].m_UV.dx=dScale*m_nodes[i].m_UV.dx;?????????????????????????????
  • ????????m_nodes[i].m_UV.dy=dScale*m_nodes[i].m_UV.dy;???
  • ????}??
  • }??
  • ??
  • ??
  • ??
  • void?CStrokeParameterization::list_neighbor_from_node(DEMNode_pointer?node,???
  • ????????????????????????????????????????????????????????????????????std::vector<DEMNode_pointer>&?storage,??
  • ????????????????????????????????????????????????????????????????????std::vector<double>&?distances)??
  • {??
  • ????vertex_pointer?v?=?node->vertex();??
  • ????assert(storage.size()?==?distances.size());??
  • ??
  • ????for(unsigned?i=0;?i<v->adjacent_edges().size();?++i)??
  • ????{??
  • ????????edge_pointer?e?=?v->adjacent_edges()[i];??
  • ????????vertex_pointer?new_v?=?e->opposite_vertex(v);??
  • ????????DEMNode_pointer?DEMNew_node=&m_nodes[node_index(new_v)];??
  • ????????double?l=e->length();??
  • ???????if(DEMNew_node->m_VisitFlag!=CDEMNode::Frozen)??
  • ???????{??
  • ???????????storage.push_back(DEMNew_node);??
  • ???????????distances.push_back(e->length());??
  • ???????}??????????
  • ????}??
  • }??
  • ??
  • ??
  • unsigned?CStrokeParameterization::?node_index(vertex_pointer?v)???????
  • {??
  • ????return?v->id();??
  • };??

  • [cpp]?view plaincopy
  • //求側(cè)地矢量的公式??
  • CVector2D?CStrokeParameterization::Average_GVector(int?q)??
  • {?????
  • ??
  • ????CVector2D?AverageGvector;??
  • ????vector<int>?neighbor=Tmesh->neighbors[q];??
  • ????CVector3D?sume1;??
  • ????double?weight;??
  • ????double??sumweight=0.0;??
  • ????for(int?i=0;i<neighbor.size();i++)??
  • ????{?????
  • ????????if?(m_nodes[neighbor[i]].m_VisitFlag==CDEMNode::Frozen)??
  • ???????{???
  • ????????vec?pq=Tmesh->vertices[q]-Tmesh->vertices[neighbor[i]];??
  • ????????weight=1.0/len(pq);??
  • ????????CVector3D?pq0(pq[0],pq[1],pq[2]);??
  • ????????pq0=pq0*AlignNormal(q,neighbor[i]);??
  • ????????CVector2D?uvofq(pq0|m_nodes[neighbor[i]].m_e1,pq0|m_nodes[neighbor[i]].m_e2);??
  • ????????uvofq=uvofq+m_nodes[neighbor[i]].m_UV;??
  • ????????uvofq=uvofq*weight;??
  • ????????AverageGvector=AverageGvector+uvofq;??
  • ????????sumweight+=weight;??
  • ???????}??
  • ????}??
  • ????AverageGvector=AverageGvector/sumweight;??
  • ???
  • ??
  • ??return?AverageGvector;??
  • }??

  • [cpp]?view plaincopy
  • //求p的法向量往q法向量的旋轉(zhuǎn)矩陣??
  • CMatrix3D?CStrokeParameterization::AlignNormal(int?p,int?q)??
  • {??
  • ????double?angle=0.0;??
  • ????vec?p_nor,q_nor;??
  • ????CVector3D?p_Nor,q_Nor,Cross_qN_pN;??
  • ????CMatrix3D?rotMtrx1;??
  • ????p_nor=VertexNormals[p];??
  • ????q_nor=VertexNormals[q];??
  • ????p_Nor=CVector3D(p_nor[0],p_nor[1],p_nor[2]);??
  • ????q_Nor=CVector3D(q_nor[0],q_nor[1],q_nor[2]);??
  • ????p_Nor.Normalize();??
  • ????q_Nor.Normalize();??
  • ????angle=p_Nor|q_Nor;??
  • ????angle=acos(angle);??????????????????????????????????????
  • ????Cross_qN_pN=p_Nor*q_Nor;??
  • ????rotMtrx1=rotMtrx1.CreateRotateMatrix(angle,Cross_qN_pN);??
  • ??
  • return?rotMtrx1;??
  • }??
  • //求p的法向量往q法向量的旋轉(zhuǎn)矩陣,參數(shù)為兩個(gè)點(diǎn)的法向量??
  • CMatrix3D?CStrokeParameterization::AlignNormaln(CVector3D?np,CVector3D?nq)??
  • {??
  • ????double?angle=0.0;??
  • ????CVector3D?p_Nor,q_Nor,Cross_qN_pN;??
  • ????CMatrix3D?rotMtrx1;??
  • ????p_Nor=np;??
  • ????q_Nor=nq;??
  • ????p_Nor.Normalize();??
  • ????q_Nor.Normalize();??
  • ????angle=p_Nor|q_Nor;??
  • ????angle=acos(angle);??????????????????????????????????????
  • ????Cross_qN_pN=p_Nor*q_Nor;??
  • ????rotMtrx1=rotMtrx1.CreateRotateMatrix(angle,Cross_qN_pN);??
  • ????return?rotMtrx1;??
  • }??
  • Frame Field的更新顯示結(jié)果:

    這種沿著曲線進(jìn)行參數(shù)化的paper較少,還有另外一篇paper:《Texture Brush: An Interactive Surface Texturing Interface》也是沿著曲線參數(shù)化,不過(guò)效率速度都感覺(jué)沒(méi)有這個(gè)爽。不過(guò)那篇paper的紋理貼圖的效果看起來(lái)倒是挺漂亮的:
    貼圖

    這篇paper就講到這里吧。參數(shù)化在Siggraph上面的paper還是很多的,每一年都有Parameterization相關(guān)的模塊,所以還有很多paper等著我們?nèi)W(xué)習(xí)

    本文地址:http://blog.csdn.net/hjimce/article/details/46489913?? ? 作者:hjimce ? ? 聯(lián)系qq:1393852684 ??更多資源請(qǐng)關(guān)注我的博客:http://blog.csdn.net/hjimce? ? ? ? ? ? ? ? 原創(chuàng)文章,轉(zhuǎn)載請(qǐng)保留本行信息。

    參考文獻(xiàn):

    1、Texture Brush: An Interactive Surface Texturing Interface

    2、Stroke Parameterization

    3、Interactive Decal Compositing with Discrete Exponential Maps

    總結(jié)

    以上是生活随笔為你收集整理的图形处理(十一)Stroke Parameterization的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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