Changeset 43:f445f53bccb4 in rrlib_geometry


Ignore:
Timestamp:
05.06.2012 13:53:08 (7 years ago)
Author:
Patrick Fleischmann <fleischmann@…>
Branch:
default
Phase:
public
Message:

Fixed GetClosestPoint for Bezier curves due the previos implementation fails for S-shaped curves. Improved implementation works with the lines of the control polygon.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • curves/tBezierCurve.hpp

    r42 r43  
    294294  tSubdivision subdivision(this->GetSubdivision()); 
    295295 
    296   tLineSegment<Tdimension, TElement> first_segment_base_line(subdivision.first.ControlPoints()[0], subdivision.first.ControlPoints()[Tdegree]); 
    297   tLineSegment<Tdimension, TElement> second_segment_base_line(subdivision.second.ControlPoints()[0], subdivision.second.ControlPoints()[Tdegree]); 
    298  
    299   typename tShape::tPoint first_candidate = first_segment_base_line.GetClosestPoint(reference_point); 
    300   typename tShape::tPoint second_candidate = second_segment_base_line.GetClosestPoint(reference_point); 
    301  
    302   double squared_distance_to_first_candidate = (reference_point - first_candidate).SquaredLength(); 
    303   double squared_distance_to_second_candidate = (reference_point - second_candidate).SquaredLength(); 
     296  double squared_distance_to_first_candidate = std::numeric_limits<double>::max(); 
     297  double squared_distance_to_second_candidate = std::numeric_limits<double>::max(); 
     298 
     299  for (unsigned int i = 0; i < Tdegree; ++i) 
     300  { 
     301    tLineSegment<Tdimension, TElement> first_segment_base_line(subdivision.first.ControlPoints()[i], subdivision.first.ControlPoints()[i + 1]); 
     302    tLineSegment<Tdimension, TElement> second_segment_base_line(subdivision.second.ControlPoints()[i], subdivision.second.ControlPoints()[i + 1]); 
     303 
     304    typename tShape::tPoint first_candidate = first_segment_base_line.GetClosestPoint(reference_point); 
     305    typename tShape::tPoint second_candidate = second_segment_base_line.GetClosestPoint(reference_point); 
     306 
     307    double squared_distance_to_first = (reference_point - first_candidate).SquaredLength(); 
     308    double squared_distance_to_second = (reference_point - second_candidate).SquaredLength(); 
     309 
     310    if (squared_distance_to_first < squared_distance_to_first_candidate) 
     311    { 
     312      squared_distance_to_first_candidate = squared_distance_to_first; 
     313    } 
     314 
     315    if (squared_distance_to_second < squared_distance_to_second_candidate) 
     316    { 
     317      squared_distance_to_second_candidate = squared_distance_to_second; 
     318    } 
     319  } 
    304320 
    305321  if (squared_distance_to_first_candidate < squared_distance_to_second_candidate) 
     
    307323    if (subdivision.first.GetTwist() < 1E-6) 
    308324    { 
    309       return first_candidate; 
     325      tLineSegment<Tdimension, TElement> first_segment_base_line(subdivision.first.ControlPoints()[0], subdivision.first.ControlPoints()[Tdegree]); 
     326      return first_segment_base_line.GetClosestPoint(reference_point); 
    310327    } 
    311328    return subdivision.first.GetClosestPoint(reference_point); 
     
    314331  if (subdivision.second.GetTwist() < 1E-6) 
    315332  { 
    316     return second_candidate; 
     333    tLineSegment<Tdimension, TElement> second_segment_base_line(subdivision.second.ControlPoints()[0], subdivision.second.ControlPoints()[Tdegree]); 
     334    return second_segment_base_line.GetClosestPoint(reference_point); 
    317335  } 
    318336  return subdivision.second.GetClosestPoint(reference_point); 
Note: See TracChangeset for help on using the changeset viewer.