#include "AdjacentInfo.h" // 索引相同的顶点是同一个点 bool operator==(const FAdjacentVertex& left, const FAdjacentVertex& right) { return left.Index() == right.Index(); } // 只要边连接的两个顶点相同(顺序可以相反)就是同一个边 bool operator==(const FAdjacentEdge& left, const FAdjacentEdge& right) { return (left.V1() == right.V1() && left.V2() == right.V2()) || (left.V1() == right.V2() && left.V2() == right.V1()); } void FAdjacentVertex::CalculateType() { // 是边界点 if (inBorder) { if (angle > 1.5f * PI) { type = 2.0f; } else if (angle < 0.5f * PI) { type = 3.0f; } else { type = 1.0f; } } else { type = 0.0f; } } void FAdjacentVertex::CalculateSoftNormalByAdjVertice() { if (!inBorder) return; uint32 innerAdjVerticeCount = 0; for (FAdjacentVertex* v: adjVertice) if (!v->inBorder) ++innerAdjVerticeCount; softNormal = FVector::ZeroVector; // 如果相邻顶点有内部顶点,使用内部顶点方向 if (innerAdjVerticeCount) { for (FAdjacentVertex* v: adjVertice) { if (!v->inBorder) { FVector dir = pos - v->pos; dir.Normalize(); softNormal += dir; } } } else { for (FAdjacentVertex* v: adjVertice) { FVector dir = pos - v->pos; dir.Normalize(); softNormal += dir; } } softNormal.Normalize(); } void FAdjacentVertex::ProjectSoftNormalOnNormalPlane() { normal.Normalize(); if (inBorder) { softNormal.Normalize(); softNormal -= FVector::DotProduct(normal, softNormal) * normal; softNormal.Normalize(); } } FAdjacentEdge::FAdjacentEdge(FAdjacentVertex& v1, FAdjacentVertex& v2): v1(v1), v2(v2), count(1) { length = (v1.Pos() - v2.Pos()).Size(); } void FAdjacentEdge::SetInBorder() { v1.InBorder() = true; v2.InBorder() = true; } void FAdjacentEdge::AddVertexToEdge() { v1.AdjVertice().Add(&v2); v2.AdjVertice().Add(&v1); } FAdjacentPolygon::FAdjacentPolygon(const TArray& Vertices, const TArray& Edges, int32 N) : v(Vertices), e(Edges), n(N) { // 计算面法线 FVector dirAB = V(1).Pos() - V(0).Pos(); FVector dirBC = V(2).Pos() - V(1).Pos(); normal = FVector::CrossProduct(dirAB, dirBC); normal.Normalize(); } void FAdjacentPolygon::CalculateVertexNormal() { // 对于三角形的每个顶点,计算该顶点角度和方向 for (int i = 0; i < n; ++i) { // 顶点 FAdjacentVertex& A = V(i); FAdjacentVertex& B = V((i - 1 + n) % n); FAdjacentVertex& C = V((i + 1) % n); FVector dirBA = A.Pos() - B.Pos(); FVector dirCA = A.Pos() - C.Pos(); dirBA.Normalize(); dirCA.Normalize(); float cosA = FVector::DotProduct(dirBA, dirCA); // 顶点A的角度 float angle = FMath::Acos(cosA); FVector vNormal = normal * angle; A.Normal() += vNormal; if (A.InBorder()) // 边界顶点 计算边界延伸方向 { // angle为权重 A.SoftNormal() += (dirBA + dirCA).GetUnsafeNormal() * angle; } A.Angle() += angle; } }