Example #1
0
double tdistance(const TSegment &segment, const TPointD &point) {
  TPointD v1 = segment.getP1() - segment.getP0();
  TPointD v2 = point - segment.getP0();
  TPointD v3 = point - segment.getP1();

  if (v2 * v1 <= 0)
    return tdistance(point, segment.getP0());
  else if (v3 * v1 >= 0)
    return tdistance(point, segment.getP1());

  return fabs(v2 * rotate90(normalize(v1)));
}
inline bool JunctionArea::sequencesPullBack() {
  std::vector<EnteringSequence>::iterator a;
  double alongLinePosition, distanceFromLine;
  unsigned int i, iLink, tail;
  TPointD P;

  for (a = m_enteringSequences.begin(); a != m_enteringSequences.end(); ++a) {
    i     = a->m_head;
    iLink = a->m_headLink;
    // NOTE: updated tails are stored this way, *DONT* look in a->m_tail
    // because these typically store old infos
    tail =
        currJSGraph->getNode(a->m_initialJoint).getLink(a->m_outerLink)->m_tail;
    P = planeProjection(*a->m_graphHolder->getNode(a->m_head));

    while (i != tail) {
      alongLinePosition = a->m_direction * (m_newJointPosition - P);
      distanceFromLine  = tdistance(m_newJointPosition, a->m_direction, P);

      if (alongLinePosition >= 0 &&
          (distanceFromLine / alongLinePosition) <= 0.5)
        goto found_pull_back;

      // We then take the next arc and check it

      if (!a->m_graphHolder->getNode(i).getLink(iLink)->hasAttribute(
              SkeletonArc::ROAD))
        return 0;  // Pull back failed

      a->next(i, iLink);

      P = planeProjection(*a->m_graphHolder->getNode(i));
      if (tdistance(P, a->m_direction, m_newJointPosition) >
          std::max(pullBackMul * a->m_height, 1.0))
        return 0;  // Pull back failed
    }

    // Now checking opposite sequence extremity
    if (alongLinePosition < 0 || (distanceFromLine / alongLinePosition) > 0.5)
      return 0;

  found_pull_back:

    a->m_head     = i;
    a->m_headLink = iLink;
  }

  return 1;
}
void MyInbetweener::stabilizeSegments(TStroke *stroke)
{
	for (int j = 0; j + 4 < stroke->getControlPointCount(); j += 4) {
		TThickPoint q0 = stroke->getControlPoint(j);
		TThickPoint q4 = stroke->getControlPoint(j + 4);
		TPointD p0 = convert(q0);
		TPointD p1 = convert(stroke->getControlPoint(j + 1));
		TPointD p2 = convert(stroke->getControlPoint(j + 2));
		TPointD p3 = convert(stroke->getControlPoint(j + 3));
		TPointD p4 = convert(q4);
		TPointD v = normalize(p4 - p0);
		TPointD u = rotate90(v);
		double eps = tdistance(p0, p4) * 0.1;
		if (fabs(u * (p2 - p0)) < eps &&
			fabs(u * (p1 - p0)) < eps &&
			fabs(u * (p3 - p0)) < eps) {
			double e = 0.001;
			double d2 = norm2(p4 - p0);
			if (e * e * 6 * 6 > d2)
				e = sqrt(d2) / 6;
			TThickPoint q1(p0 + v * e, q0.thick);
			TThickPoint q3(p4 - v * e, q4.thick);
			stroke->setControlPoint(j + 1, q1);
			stroke->setControlPoint(j + 3, q3);
		}
	}
}
inline bool JunctionArea::solveJunctionPosition()
{
	std::vector<EnteringSequence>::iterator a;
	double Sx2 = 0, Sy2 = 0, Sxy = 0;
	TPointD P, v, b;
	double h;

	//Build preliminary sums for the linear system
	for (a = m_enteringSequences.begin(); a != m_enteringSequences.end(); ++a) {
		h = a->m_height;
		v = a->m_direction;
		P = planeProjection(*a->m_graphHolder->getNode(a->m_head));

		//Height-weighted problem
		Sx2 += sq(v.x) * h;
		Sy2 += sq(v.y) * h;
		Sxy += v.x * v.y * h;
		b.x += h * (sq(v.y) * P.x - (v.x * v.y * P.y));
		b.y += h * (sq(v.x) * P.y - (v.x * v.y * P.x));
	}

	//First check problem determinant
	double det = Sx2 * Sy2 - sq(Sxy);
	if (fabs(det) < 0.1)
		return 0;

	//Now construct linear system
	TAffine M(Sx2 / det, Sxy / det, 0, Sxy / det, Sy2 / det, 0);

	m_newJointPosition = M * b;

	//Finally, check if J is too far from the line extensions of the entering
	//sequences
	for (a = m_enteringSequences.begin(); a != m_enteringSequences.end(); ++a) {
		P = planeProjection(*a->m_graphHolder->getNode(a->m_head));
		if (tdistance(m_newJointPosition, a->m_direction, P) > a->m_height * lineDistMul)
			return 0;
	}

	return 1;
}
Example #5
0
void renormalizeImage(TVectorImage *vi)
{
	int i, j;
	int n = vi->getStrokeCount();
	std::vector<ControlPoint> points;
	points.reserve(n * 2);
	for (i = 0; i < n; i++) {
		TStroke *stroke = vi->getStroke(i);
		int m = stroke->getControlPointCount();
		if (m > 0) {
			if (m == 1)
				points.push_back(ControlPoint(stroke, 0));
			else {
				points.push_back(ControlPoint(stroke, 0));
				points.push_back(ControlPoint(stroke, m - 1));
			}
		}
	}
	int count = points.size();
	for (i = 0; i < count; i++) {
		ControlPoint &pi = points[i];
		TPointD posi = pi.getPoint();
		TPointD center = posi;
		std::vector<int> neighbours;
		neighbours.push_back(i);
		for (j = i + 1; j < count; j++) {
			TPointD posj = points[j].getPoint();
			double d = tdistance(posj, posi);
			if (d < 0.01) {
				neighbours.push_back(j);
				center += posj;
			}
		}
		int m = neighbours.size();
		if (m == 1)
			continue;
		center = center * (1.0 / m);
		for (j = 0; j < m; j++)
			points[neighbours[j]].setPoint(center);
	}
}