@@ -128,6 +128,18 @@ namespace geode
128128 return std::nullopt ;
129129 }
130130
131+ template < typename PointType, index_t dimension >
132+ template < index_t T >
133+ typename std::enable_if< T == 3 , std::optional< Vector3D > >::type
134+ GenericTriangle< PointType, dimension >::strict_normal() const
135+ {
136+ if ( const auto result = strict_pivot_and_normal () )
137+ {
138+ return result->second ;
139+ }
140+ return std::nullopt ;
141+ }
142+
131143 template < typename PointType, index_t dimension >
132144 template < index_t T >
133145 typename std::enable_if< T == 3 , std::optional< Plane > >::type
@@ -166,6 +178,27 @@ namespace geode
166178 return std::nullopt ;
167179 }
168180
181+ template < typename PointType, index_t dimension >
182+ template < index_t T >
183+ typename std::enable_if< T == 3 ,
184+ std::optional< std::pair< local_index_t , Vector3D > > >::type
185+ GenericTriangle< PointType, dimension >::strict_pivot_and_normal() const
186+ {
187+ const auto result = simple_pivot_and_normal (
188+ { vertices_[0 ], vertices_[1 ], vertices_[2 ] } );
189+ if ( !result )
190+ {
191+ return std::nullopt ;
192+ }
193+ if ( result->pivot != NO_LID )
194+ {
195+ return std::optional< std::pair< local_index_t , Vector3D > >{
196+ std::make_pair ( result->pivot , result->normal )
197+ };
198+ }
199+ return std::nullopt ;
200+ }
201+
169202 template < typename PointType, index_t dimension >
170203 template < index_t T >
171204 typename std::enable_if< T == 3 ,
@@ -184,6 +217,28 @@ namespace geode
184217 std::make_pair ( result->pivot , result->normal )
185218 };
186219 }
220+ const auto max = absl::c_max_element ( result->lengths );
221+ const local_index_t longest_e =
222+ std::distance ( result->lengths .begin (), max );
223+ const Point3D& point0 = vertices_[longest_e];
224+ const auto e1 = longest_e == 2 ? 0 : longest_e + 1 ;
225+ const Point3D& point1 = vertices_[e1 ];
226+ const auto e2 = e1 == 2 ? 0 : e1 + 1 ;
227+ const Point3D& point2 = vertices_[e2 ];
228+ if ( point_segment_distance ( point2, { point0, point1 } )
229+ > GLOBAL_EPSILON )
230+ {
231+ const auto ratio = result->lengths [e2 ]
232+ / ( result->lengths [e2 ] + result->lengths [e1 ] );
233+ const auto new_point = point0 * ( 1 . - ratio ) + point1 * ratio;
234+ const auto result_left =
235+ simple_pivot_and_normal ( { point0, new_point, point2 } );
236+ if ( !result_left || result_left->pivot == NO_LID )
237+ {
238+ return std::nullopt ;
239+ }
240+ return std::make_pair ( e2 , result_left->normal );
241+ }
187242 return std::nullopt ;
188243 }
189244
0 commit comments