Ignore:
Timestamp:
Aug 20, 2014, 1:07:11 PM (11 years ago)
Author:
Frederik Heber <heber@…>
Children:
c56380
Parents:
d635829
git-author:
Frederik Heber <heber@…> (07/20/14 11:26:01)
git-committer:
Frederik Heber <heber@…> (08/20/14 13:07:11)
Message:

tempcommit: Fixes to calculateCenterOfMinimumDistance. Merge with 2056d8e9

  • we also check whether all points lie on a great circle, which also results in non-uniqueness.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Fragmentation/Exporters/SphericalPointDistribution.cpp

    rd635829 r4a44ed  
    144144      return center;
    145145    // one position given: return it directly
    146     if (_positions.size() == (size_t)1)
    147       return _positions[0];
     146    if (_indices.size() == (size_t)1)
     147      return _positions[*_indices.begin()];
    148148    // two positions on a line given: return closest point to (1.,0.,0.)
    149     if (fabs(_positions[0].ScalarProduct(_positions[1]) + 1.)
    150         < std::numeric_limits<double>::epsilon()*1e4) {
    151       Vector candidate;
    152       if (_positions[0].ScalarProduct(center) > _positions[1].ScalarProduct(center))
    153         candidate = _positions[0];
    154       else
    155         candidate = _positions[1];
    156       // non-uniqueness: all positions on great circle, normal to given line are valid
    157       // so, we just pick one because returning a unique point is topmost priority
    158       Vector normal;
    159       normal.GetOneNormalVector(candidate);
    160       Vector othernormal = candidate;
    161       othernormal.VectorProduct(normal);
    162       // now both normal and othernormal describe the plane containing the great circle
    163       Plane greatcircle(normal, zeroVec, othernormal);
    164       // check which axis is contained and pick the one not
    165       if (greatcircle.isContained(center)) {
    166         center = Vector(0.,1.,0.);
    167         if (greatcircle.isContained(center))
    168           center = Vector(0.,0.,1.);
    169         // now we are done cause a plane cannot contain all three axis vectors
    170       }
    171       center = greatcircle.getClosestPoint(candidate);
    172       // assure length of 1
    173       center.Normalize();
     149//    IndexList_t::const_iterator indexiter = _indices.begin();
     150//    const unsigned int firstindex = *indexiter++;
     151//    const unsigned int secondindex = *indexiter;
     152//    if ( fabs(_positions[firstindex].ScalarProduct(_positions[secondindex]) + 1.)
     153//        < std::numeric_limits<double>::epsilon()*1e4) {
     154//      Vector candidate;
     155//      if (_positions[firstindex].ScalarProduct(center) > _positions[secondindex].ScalarProduct(center))
     156//        candidate = _positions[firstindex];
     157//      else
     158//        candidate = _positions[secondindex];
     159//      // non-uniqueness: all positions on great circle, normal to given line are valid
     160//      // so, we just pick one because returning a unique point is topmost priority
     161//      Vector normal;
     162//      normal.GetOneNormalVector(candidate);
     163//      Vector othernormal = candidate;
     164//      othernormal.VectorProduct(normal);
     165//      // now both normal and othernormal describe the plane containing the great circle
     166//      Plane greatcircle(normal, zeroVec, othernormal);
     167//      // check which axis is contained and pick the one not
     168//      if (greatcircle.isContained(center)) {
     169//        center = Vector(0.,1.,0.);
     170//        if (greatcircle.isContained(center))
     171//          center = Vector(0.,0.,1.);
     172//        // now we are done cause a plane cannot contain all three axis vectors
     173//      }
     174//      center = greatcircle.getClosestPoint(candidate);
     175//      // assure length of 1
     176//      center.Normalize();
     177//
     178//      return center;
     179//    }
     180    // given points lie on a great circle and go completely round it
     181    // two or more positions on a great circle given: return closest point to (1.,0.,0.)
     182    {
     183      bool AllNormal = true;
     184      Vector Normal;
     185      {
     186        IndexList_t::const_iterator indexiter = _indices.begin();
     187        Normal = _positions[*indexiter++];
     188        Normal.VectorProduct(_positions[*indexiter++]);
     189        Normal.Normalize();
     190        for (;(AllNormal) && (indexiter != _indices.end()); ++indexiter)
     191          AllNormal &= _positions[*indexiter].IsNormalTo(Normal, 1e-8);
     192      }
     193      double AngleSum = 0.;
     194      if (AllNormal) {
     195        // check by angle sum whether points go round are cover just one half
     196        IndexList_t::const_iterator indexiter = _indices.begin();
     197        Vector CurrentVector = _positions[*indexiter++];
     198        for(; indexiter != _indices.end(); ++indexiter) {
     199          AngleSum += CurrentVector.Angle(_positions[*indexiter]);
     200          CurrentVector = _positions[*indexiter];
     201        }
     202      }
     203      if (AngleSum - M_PI > std::numeric_limits<double>::epsilon()*1e4) {
     204//        Vector candidate;
     205//        double oldSKP = -1.;
     206//        for (IndexList_t::const_iterator iter = _indices.begin();
     207//            iter != _indices.end(); ++iter) {
     208//          const double newSKP = _positions[*iter].ScalarProduct(center);
     209//          if (newSKP > oldSKP) {
     210//            candidate = _positions[*iter];
     211//            oldSKP = newSKP;
     212//          }
     213//        }
     214        // non-uniqueness: all positions on great circle, normal to given line are valid
     215        // so, we just pick one because returning a unique point is topmost priority
     216//        Vector normal;
     217//        normal.GetOneNormalVector(candidate);
     218//        Vector othernormal = candidate;
     219//        othernormal.VectorProduct(normal);
     220//        // now both normal and othernormal describe the plane containing the great circle
     221//        Plane greatcircle(normal, zeroVec, othernormal);
     222        // check which axis is contained and pick the one not
     223//        if (greatcircle.isContained(center)) {
     224//          center = Vector(0.,1.,0.);
     225//          if (greatcircle.isContained(center))
     226//            center = Vector(0.,0.,1.);
     227//          // now we are done cause a plane cannot contain all three axis vectors
     228//        }
     229//        center = greatcircle.getClosestPoint(candidate);
     230//        center = greatcircle.getNormal();
     231        center = Normal;
     232        // assure length of 1
     233        center.Normalize();
     234
     235        return center;
     236      }
    174237    }
    175238  }
     
    179242  if (!center.IsZero()) {
    180243    center.Normalize();
    181     LOG(4, "DEBUG: Starting with geographical midpoint of " << _positions << " under indices "
     244    LOG(5, "DEBUG: Starting with geographical midpoint of " << _positions << " under indices "
    182245        << _indices << " is " << center);
    183246  } else {
    184247    // any point is good actually
    185248    center = _positions[0];
    186     LOG(4, "DEBUG: Starting with first position " << center);
     249    LOG(5, "DEBUG: Starting with first position " << center);
    187250  }
    188251
    189252  // calculate initial MinimumDistance
    190253  double MinimumDistance = calculateMinimumDistance(center, _positions, _indices);
    191   LOG(5, "DEBUG: MinimumDistance to this center is " << MinimumDistance);
     254  LOG(6, "DEBUG: MinimumDistance to this center is " << MinimumDistance);
    192255
    193256  // check all present points whether they may serve as a better center
     
    199262      MinimumDistance = candidateDistance;
    200263      center = centerCandidate;
    201       LOG(5, "DEBUG: new MinimumDistance to current test point " << MinimumDistance
     264      LOG(6, "DEBUG: new MinimumDistance to current test point " << MinimumDistance
    202265          << " is " << center);
    203266    }
    204267  }
    205   LOG(5, "DEBUG: new MinimumDistance to center " << center << " is " << MinimumDistance);
     268  LOG(6, "DEBUG: new MinimumDistance to center " << center << " is " << MinimumDistance);
    206269
    207270  // now iterate over TestDistance
     
    231294        center = centerCandidate;
    232295        updatedflag = true;
    233         LOG(5, "DEBUG: new MinimumDistance to test point at " << *angleiter/M_PI*180.
     296        LOG(7, "DEBUG: new MinimumDistance to test point at " << *angleiter/M_PI*180.
    234297            << "° is " << MinimumDistance);
    235298      }
     
    411474      errors.second += gap*gap;
    412475    }
     476    // there is at least one distance, we've checked that before
     477    errors.second *= 1./(double)firstdistances.size();
    413478  } else {
    414479    // check whether we have any zero centers: Combining points on new sphere may result
Note: See TracChangeset for help on using the changeset viewer.