예제 #1
0
파일: algebra.cpp 프로젝트: vitos1/imago
Vec2d Algebra::linesIntersection(const Settings& vars, const Vec2d &p11, const Vec2d &p12,
                                  const Vec2d &p21, const Vec2d &p22 )
{
   Line l1 = points2line(p11, p12);
   Line l2 = points2line(p21, p22);
   double den = l1.A * l2.B - l2.A * l1.B;

   if (absolute(den) < vars.routines.Algebra_IntersectionEps)
   {
      Vec2d res;
      res.add(p11);
      res.add(p21);
      res.scale(0.5); // average
      return res;
   }
   else
   {
      return linesIntersection(vars, l1, l2);
   }
}
예제 #2
0
Vec2d Algebra::linesIntersection( const Vec2d &p11, const Vec2d &p12,
                                  const Vec2d &p21, const Vec2d &p22 )
{
   Line l1 = points2line(p11, p12);
   Line l2 = points2line(p21, p22);
   double den = l1.A * l2.B - l2.A * l1.B;

   //Nonstandart behaviour
   if (absolute(den) < 0.01) //"Constants" ?
   {
      Vec2d res;
      res.add(p11);
      res.add(p21);
      res.scale(0.5);
      return res;
   }
   else
   {
      return linesIntersection(l1, l2);
   }
}
예제 #3
0
void Molecule::mapLabels(const Settings& vars, std::deque<Label> &unmapped_labels )
{
   double space, space2;
   double bl = bondLength();
   if (bl > vars.molecule.LengthValue_long)
	   space = vars.molecule.LengthFactor_long;
   else if (bl > vars.molecule.LengthValue_medium)
	   space = vars.molecule.LengthFactor_medium; 
   else
	   space = vars.molecule.LengthFactor_default; 

//   printf("****: %lf %lf\n", bl, space);

   std::vector<Skeleton::Vertex> nearest;

   labels.assign(_labels.begin(), _labels.end());
   
   for (size_t i = 0; i < labels.size(); ++i)
   {
      Label &l = labels[i];
#ifdef DEBUG
      printf("LABELS: %d %d\n", l.rect.x, l.rect.y);
#endif


      nearest.clear();
	  space = l.MaxSymbolWidth() * vars.molecule.SpaceMultiply;
	  space2 = l.rect.width < l.rect.height ? l.rect.width : l.rect.height;
	   
      for (SkeletonGraph::edge_iterator begin = _g.edgeBegin(), end = _g.edgeEnd(); begin != end; ++begin)
      {
         SkeletonGraph::edge_descriptor e = *begin;
         if (vars.checkTimeLimit())
			  throw ImagoException("Timelimit exceeded");

         double d1, d2;
         d1 = d2 = DIST_INF;

		 if(_g.getDegree(e.m_source) > 1 &&
			 _g.getDegree(e.m_target) > 1)
			 continue;

		 if (_g.getDegree(e.m_source) == 1)
            d1 = Algebra::distance2rect(_g.getVertexPosition(e.m_source), l.rect);

         if (_g.getDegree(e.m_target) == 1)
            d2 = Algebra::distance2rect(_g.getVertexPosition(e.m_target), l.rect);
         
         auto v_m_target = _g.getVertexPosition(e.m_target);
         auto v_m_source = _g.getVertexPosition(e.m_source);

		 if (d1 <= d2 && ((testCollision(v_m_target, v_m_source, l.rect) &&
			 testNear(v_m_source, l.rect, space)) ||
			 testNear(v_m_source, l.rect, space2/2)))
            nearest.push_back(e.m_source);
         else if (d2 < d1 && ((testCollision(v_m_source, v_m_target, l.rect) &&
			 testNear(v_m_target, l.rect, space)) ||
			 testNear(v_m_target, l.rect, space2/2)))
            nearest.push_back(e.m_target);
	  }

     for (SkeletonGraph::vertex_iterator begin = _g.vertexBegin(), end = _g.vertexEnd(); begin != end; ++begin)
	  {
        SkeletonGraph::vertex_descriptor v = *begin;
        auto v_position = _g.getVertexPosition( v);
            
		  if(_g.getDegree(v) != 2)
			  continue;
		  if(!testNear(v_position, l.rect, space2/2))
			  continue;

        std::deque<Skeleton::Vertex> neighbors;
		  Skeleton::SkeletonGraph::adjacency_iterator b_e, e_e;
		  b_e = _g.adjacencyBegin(v);
		  e_e = _g.adjacencyEnd(v);
		  neighbors.assign(b_e, e_e);

        Skeleton::Edge edge1 = _g.getEdge(neighbors[0], v).first;
        Skeleton::Edge edge2 = _g.getEdge(neighbors[1], v).first;
		  BondType t1 = getBondType(edge1);
		  BondType t2 = getBondType(edge2);

		  if( t1 != BT_SINGLE || t2 != BT_SINGLE)
			  continue;

		  Vec2d p_v = _g.getVertexPosition(v);
		  Vec2d p1 = _g.getVertexPosition(neighbors[0]);
		  Vec2d p2 = _g.getVertexPosition(neighbors[1]);

		  Vec2d ap1, ap2;
		  ap1.diff(p1, p_v);
		  ap2.diff(p2, p_v);

		  if( testCollision(p1, p_v, l.rect) && 
			  testCollision(p2, p_v, l.rect) &&
			  testNear(p_v, l.rect, space) &&
			  !testNear( p1, l.rect, space) &&
			  !testNear( p2, l.rect, space) )
		  {
			
			  removeBond(edge1);
           Vertex v_d = addVertex(p_v);
			  addBond(neighbors[0], v_d, BT_SINGLE, true);
			  nearest.push_back(v_d);
			  nearest.push_back(v);
		  }
	  }

      size_t s = nearest.size();
      if (s == 0)
      {
         unmapped_labels.push_back(l);
         continue;
      }

      if (s == 1)
      {
         _mapping[nearest[0]] = &l;
         continue;
      }

      Vec2d middle;
      for (int j = 0; j < s; j++)
      {
         for (int k = j + 1; k < s; k++)
         {
			   if (vars.checkTimeLimit())
			      throw ImagoException("Timelimit exceeded");
            Skeleton::Vertex a, b;
            Skeleton::Vertex c, d;
            a = nearest[j];
            b = nearest[k];
            c = *_g.adjacencyBegin(a);
            d = *_g.adjacencyBegin(b);

            Vec2d n1, n2;
            Vec2d v_a, v_b, v_c, v_d;
            v_a = _g.getVertexPosition(a);
            v_b = _g.getVertexPosition(b);
            v_c = _g.getVertexPosition(c);
            v_d = _g.getVertexPosition(d);
            n1.diff(v_a, v_c);
            n2.diff(v_b, v_d);

            Vec2d m;

            double ang = Vec2d::angle(n1, n2);
            if (fabs(ang) < vars.molecule.AngleTreshold ||
                fabs(ang - PI) < vars.molecule.AngleTreshold )
            {
               m.middle(v_a, v_b);
            }
            else
            {
               m.copy(Algebra::linesIntersection(vars, v_a, v_c, v_b, v_d));
            }

            middle.add(m);
         }
      }
      
      middle.scale(2.0 / (s * (s - 1)));
      Vertex newVertex = addVertex(middle);
      for (int j = 0; j < s; j++)
      {
         Vertex e = nearest[j];
         Vertex b = *_g.adjacencyBegin(e);
         Edge bond = _g.getEdge(e, b).first;
         BondType t = _g.getEdgeBond(bond).type;

         _g.removeEdge(bond);
         _g.removeVertex(e);
         addBond(b, newVertex, t);
      }
      _mapping[newVertex] = &l;
   }

   std::deque<Skeleton::Vertex> deck;

   //Removing dots without labels
   

   for (SkeletonGraph::vertex_iterator begin = _g.vertexBegin(), end = _g.vertexEnd(); begin != end; ++begin)
   {
      SkeletonGraph::vertex_descriptor v = *begin;
      if (_g.getDegree(v) == 0 && _mapping.find(v) == _mapping.end())
         deck.push_back(v);
   }
   


   for (Skeleton::Vertex v : deck)
      _g.removeVertex(v);
}