示例#1
0
void AngleVariation::checkParentBranchIntersection(QPointF* parentBounds)
{
    QLineF sideLine1 = QLineF(parentBounds[0], parentBounds[3]);
    QLineF sideLine2 = QLineF(parentBounds[1], parentBounds[2]);

    float tempSide1 = findDistance(branchLine.p1(), closestPointOnLine(sideLine1.p1(), sideLine1.p2(), branchLine.p1()));
    float tempSide2 = findDistance(branchLine.p1(), closestPointOnLine(sideLine2.p1(), sideLine2.p2(), branchLine.p1()));

    QLineF chosenLine;
    if (tempSide1 < tempSide2)
        chosenLine = sideLine1;
    else
        chosenLine = sideLine2;

    QPointF point1 = calcVarExtremePoint(chosenLine, branchLine.p1(), length);
    QPointF point2 = findAdjacentPoint(branchLine.p1(), point1);

    QPointF control = calcVarExtremePoint(branchLine, branchLine.p1(), length);

    if (findDistance(origPoint, control) >= findDistance(point1, control))
    {
        origPoint = point1;
        variationPoint = calculateOpposingPoint(origPoint);
    }
    if (findDistance(origPoint, control) >= findDistance(point2, control))
    {
        origPoint = point2;
        variationPoint = calculateOpposingPoint(origPoint);
    }
}
示例#2
0
IC void closestPointOnTriangle(Fvector& result, const Fvector* V, const Fvector& p) {
	Fvector Rab; closestPointOnLine(Rab, V[0], V[1], p); float dAB = p.distance_to_sqr(Rab);
	Fvector Rbc; closestPointOnLine(Rbc, V[1], V[2], p); float dBC = p.distance_to_sqr(Rbc);
	Fvector Rca; closestPointOnLine(Rca, V[2], V[0], p); float dCA = p.distance_to_sqr(Rca);
	
	float min = dAB;
	result.set(Rab);
	if (dBC < min) {
		min = dBC;
		result.set(Rbc);
    }
	if (dCA < min)
		result.set(Rca);
}
示例#3
0
bool FloorManager::handleClosestPoint(int &setX, int &setY, int &setPoly) {
	int gotX = 320, gotY = 200, gotPoly = -1, i, j, xTest1, yTest1, xTest2, yTest2, closestX, closestY, oldJ, currentDistance = 0xFFFFF, thisDistance;

	for (i = 0; i < _currentFloor->numPolygons; i++) {
		oldJ = _currentFloor->polygon[i].numVertices - 1;
		for (j = 0; j < _currentFloor->polygon[i].numVertices; j++) {
			xTest1 = _currentFloor->vertex[_currentFloor->polygon[i].vertexID[j]].x;
			yTest1 = _currentFloor->vertex[_currentFloor->polygon[i].vertexID[j]].y;
			xTest2 = _currentFloor->vertex[_currentFloor->polygon[i].vertexID[oldJ]].x;
			yTest2 = _currentFloor->vertex[_currentFloor->polygon[i].vertexID[oldJ]].y;
			closestPointOnLine(closestX, closestY, xTest1, yTest1, xTest2, yTest2, setX, setY);
			xTest1 = setX - closestX;
			yTest1 = setY - closestY;
			thisDistance = xTest1 * xTest1 + yTest1 * yTest1;

			if (thisDistance < currentDistance) {
				currentDistance = thisDistance;
				gotX = closestX;
				gotY = closestY;
				gotPoly = i;
			}
			oldJ = j;
		}
	}

	if (gotPoly == -1)
		return false;
	setX = gotX;
	setY = gotY;
	setPoly = gotPoly;
	return true;
}
示例#4
0
QPointF AngleVariation::calculateOpposingPoint(QPointF point1)
{
    // Find closest point on line
    QPointF tempMidPoint = closestPointOnLine(branchLine.p1(), branchLine.p2(), point1);
    // Use closest point as midpoint to find opposing point
    QPointF adjacentPoint = findAdjacentPoint(tempMidPoint, point1);
    // Return point
    return adjacentPoint;
}
示例#5
0
/* MathStuff::distanceToLineFast
 * Returns the shortest 'distance' between the point at [x,y] and the
 * line from [x1,y1] to [x2,y2]. The distance returned isn't the
 * real distance, but can be used to find the 'closest' line to the
 * point
 *******************************************************************/
double MathStuff::distanceToLineFast(double x, double y, double x1, double y1, double x2, double y2)
{
	// Calculate intersection point
	fpoint2_t i = closestPointOnLine(x, y, x1, y1, x2, y2);

	// Return fast distance between intersection and point
	// which is the shortest distance to the line
	return (i.x-x)*(i.x-x) + (i.y-y)*(i.y-y);
}
示例#6
0
/* MathStuff::distanceToLineFast
 * Returns the shortest 'distance' between the given point and line.
 * The distance returned isn't the real distance, but can be used to
 * find the 'closest' line to the point
 *******************************************************************/
double MathStuff::distanceToLineFast(fpoint2_t point, fseg2_t line)
{
	// Calculate intersection point
	fpoint2_t i = closestPointOnLine(point, line);

	// Return fast distance between intersection and point
	// which is the shortest distance to the line
	return (i.x-point.x)*(i.x-point.x) + (i.y-point.y)*(i.y-point.y);
}
示例#7
0
/* MathStuff::distanceToLine
 * Returns the shortest distance between the point at [x,y] and the
 * line from [x1,y1] to [x2,y2]
 *******************************************************************/
double MathStuff::distanceToLine(fpoint2_t point, fseg2_t line)
{
	// Calculate intersection point
	fpoint2_t i = closestPointOnLine(point, line);

	// Return distance between intersection and point
	// which is the shortest distance to the line
	return MathStuff::distance(i, point);
}
示例#8
0
bool handleClosestPoint (int & setX, int & setY, int & setPoly) {
	int gotX = 320, gotY = 200, gotPoly = -1, i, j, xTest1, yTest1,
		xTest2, yTest2, closestX, closestY, oldJ, currentDistance = 0xFFFFF,
		thisDistance;

//	FILE * dbug = fopen ("debug_closest.txt", "at");
//	fprintf (dbug, "\nGetting closest point to %i, %i\n", setX, setY);

	for (i = 0; i < currentFloor -> numPolygons; i ++) {
		oldJ = currentFloor -> polygon[i].numVertices - 1;
		for (j = 0; j < currentFloor -> polygon[i].numVertices; j ++) {
//			fprintf (dbug, "Polygon %i, line %i... ", i, j);
			xTest1 = currentFloor -> vertex[currentFloor -> polygon[i].vertexID[j]].x;
			yTest1 = currentFloor -> vertex[currentFloor -> polygon[i].vertexID[j]].y;
			xTest2 = currentFloor -> vertex[currentFloor -> polygon[i].vertexID[oldJ]].x;
			yTest2 = currentFloor -> vertex[currentFloor -> polygon[i].vertexID[oldJ]].y;
			closestPointOnLine (closestX, closestY, xTest1, yTest1, xTest2, yTest2, setX, setY);
//			fprintf (dbug, "closest point is %i, %i... ", closestX, closestY);
			xTest1 = setX - closestX;
			yTest1 = setY - closestY;
			thisDistance = xTest1 * xTest1 + yTest1 * yTest1;
//			fprintf (dbug, "Distance squared %i\n", thisDistance);

			if (thisDistance < currentDistance) {
//				fprintf (dbug, "** We have a new winner! **\n");

				currentDistance = thisDistance;
				gotX = closestX;
				gotY = closestY;
				gotPoly = i;
			}
			oldJ = j;
		}
	}
//	fclose (dbug);

	if (gotPoly == -1) return false;
	setX = gotX;
	setY = gotY;
	setPoly = gotPoly;

	return true;
}
void PathHandler::scanCb(const sensor_msgs::LaserScan &scan)
{
	if (mFollowState != FOLLOW_STATE_BUSY || updateCurrentPosition() == false || getPathSize() == 0)
		return;

	uint32_t size = (scan.angle_max - scan.angle_min) / scan.angle_increment;
	for (uint32_t i = 0; i < size; i++)
	{
		if (scan.ranges[i] >= scan.range_max)
			continue;

		geometry_msgs::PointStamped tmp, p;
		tmp.header.frame_id = "/base_link";
		tmp.header.stamp = ros::Time(0);
		tmp.point.x = scan.ranges[i] * cosf(scan.angle_min + scan.angle_increment * i);
		tmp.point.y = scan.ranges[i] * sinf(scan.angle_min + scan.angle_increment * i);

		try
		{
			mTransformListener.transformPoint("/map", tmp, p);
		}
		catch (tf::TransformException &ex)
		{
			ROS_ERROR("%s",ex.what());
			return;
		}

		for (uint32_t j = mCurrentPathIndex; j < getPathSize() - 1; j++)
		{
			geometry_msgs::Point closest = closestPointOnLine(p.point, mPath[j].position, mPath[j+1].position);
			if (distanceBetweenPoints(p.point, closest) <= ROBOT_RADIUS)
			{
				ROS_INFO("Detected obstacle on path, resending goal. Distance: %f", distanceBetweenPoints(p.point, closest));
				resendGoal();
				return;
			}
		}
	}
}
Vector Physics::closestPointOnLine(Vector lineStart, Vector lineEnd, Vector point) {
    return closestPointOnLine(lineStart.x, lineStart.y, lineEnd.x, lineEnd.y, point.x, point.y);
}
/**
 * Updates path logic.
 */
void PathHandler::updatePath()
{
	geometry_msgs::Twist command;

	publishState();

	// no path? nothing to handle
	if (getPathSize() == 0)
		return;

	// update our position if possible.
	if (updateCurrentPosition() == false)
	{
		ROS_ERROR("Failed to update robot position.");
		return;
	}

	if (mCurrentPathIndex < getPathSize() - 1) // we are moving along a line segment in the path
	{
		geometry_msgs::Point robotPos;
		robotPos.x = mRobotPosition.getOrigin().x();
		robotPos.y = mRobotPosition.getOrigin().y();
		geometry_msgs::Point closestOnPath = closestPointOnLine(robotPos, mPath[mCurrentPathIndex].position, mPath[mCurrentPathIndex + 1].position);

		//ROS_INFO("robotPos[%lf, %lf], closestOnPath[%lf, %lf]", robotPos.x, robotPos.y, closestOnPath.x, closestOnPath.y);

		if (distanceBetweenPoints(closestOnPath, robotPos) > mResetDistanceTolerance)
		{
			ROS_INFO("Drove too far away from path, re-sending goal.");
			mFollowState = FOLLOW_STATE_IDLE;
			resendGoal();
			clearPath();
			return;
		}

		geometry_msgs::Point pointOnPath = getPointOnPathWithDist(closestOnPath, mLookForwardDistance);

		//ROS_INFO("closestOnPath[%lf, %lf], pointOnPath[%lf, %lf]", closestOnPath.x, closestOnPath.y, pointOnPath.x, pointOnPath.y);

		double angle = angleTo(pointOnPath);

		/*double robotYaw = tf::getYaw(mRobotPosition.getRotation()); // only used for printing
		ROS_INFO("Follow state: %d Robot pos: (%lf, %lf, %lf). Target pos: (%lf, %lf, %lf). RobotYaw: %lf. FocusYaw: %lf", mFollowState, mRobotPosition.getOrigin().getX(),
				mRobotPosition.getOrigin().getY(), mRobotPosition.getOrigin().getZ(), pointOnPath.x,
				pointOnPath.y, pointOnPath.z, robotYaw, angle);*/

		//ROS_INFO("Angle to path: %f", angle);

		command.linear.x = getScaledLinearSpeed(angle);
		command.angular.z = getScaledAngularSpeed(angle);

		if (distanceBetweenPoints(closestOnPath, mPath[mCurrentPathIndex + 1].position) < mDistanceTolerance)
		{
			//ROS_INFO("Moving to next line segment on path.");
			mCurrentPathIndex++;
		}

		publishLocalPath(command.linear.x * 3, angle);
	}
	else // only rotate for final yaw
	{
		double yaw = tf::getYaw(mPath[getPathSize() - 1].orientation);
		btVector3 orientation = btVector3(cos(yaw), sin(yaw), 0.0).rotate(btVector3(0,0,1), -tf::getYaw(mRobotPosition.getRotation()));
		double angle = atan2(orientation.getY(), orientation.getX());

		//ROS_INFO("Angle to final orientation: %f", angle);

		if (fabs(angle) > mFinalYawTolerance)
			command.angular.z = getScaledAngularSpeed(angle, true);
		else
		{
			// path is done!
			mFollowState = FOLLOW_STATE_FINISHED;
			clearPath();
		}

		publishLocalPath(1.0, angle);
	}

	mCommandPub.publish(command);
}
示例#12
0
// return closest point on triangle to the given point, and the distance
// betweeen them.
// If distance is greater than max_dist then skip the calculations and just return the approximate distance (anything greater than max_dist).
double mesh_core::closestPointOnTriangle(
      const Eigen::Vector3d& tri_a,
      const Eigen::Vector3d& tri_b,
      const Eigen::Vector3d& tri_c,
      const Eigen::Vector3d& point,
      Eigen::Vector3d& closest_point,
      double max_dist)
{
  Eigen::Vector3d ab = tri_b - tri_a;
  Eigen::Vector3d ac = tri_c - tri_a;
  Eigen::Vector3d n = ab.cross(ac);
  Eigen::Vector3d norm = n.normalized();

  Eigen::Vector3d ap = point - tri_a;
  double dist = norm.dot(ap);
  double abs_dist = std::abs(dist);

  if (abs_dist >= max_dist)
    return abs_dist;

  closest_point = point - dist * norm;

  if (acorn_closest_debug)
  {
    logInform(" CDB: tri_a     (%8.4f %8.4f %8.4f)",
      tri_a.x(),
      tri_a.y(),
      tri_a.z());
    logInform(" CDB: tri_b     (%8.4f %8.4f %8.4f)",
      tri_b.x(),
      tri_b.y(),
      tri_b.z());
    logInform(" CDB: tri_c     (%8.4f %8.4f %8.4f)",
      tri_c.x(),
      tri_c.y(),
      tri_c.z());
    logInform(" CDB: point     (%8.4f %8.4f %8.4f)",
      point.x(),
      point.y(),
      point.z());
    logInform(" CDB: intersect (%8.4f %8.4f %8.4f)",
      closest_point.x(),
      closest_point.y(),
      closest_point.z());
  }

  Eigen::Vector3d ab_norm = ab.cross(norm);
  if (acorn_closest_debug)
  {
    logInform(" CDB: ab_norm   (%8.4f %8.4f %8.4f) dp=%8.4f >? da=%8.4f",
      ab_norm.x(),
      ab_norm.y(),
      ab_norm.z(),
        ab_norm.dot(point),
        ab_norm.dot(tri_a));
  }
  if (ab_norm.dot(point) > ab_norm.dot(tri_a))
  {
    if (acorn_closest_debug)
    {
      logInform(" CDB: beyond ab");
    }
    return closestPointOnLine(tri_a, tri_b, point, closest_point);
  }

  Eigen::Vector3d ac_norm = ac.cross(norm);
  if (acorn_closest_debug)
  {
    logInform(" CDB: ac_norm   (%8.4f %8.4f %8.4f) dp=%8.4f <? da=%8.4f",
      ac_norm.x(),
      ac_norm.y(),
      ac_norm.z(),
        ac_norm.dot(point),
        ac_norm.dot(tri_a));
  }
  if (ac_norm.dot(point) < ac_norm.dot(tri_a))
  {
    if (acorn_closest_debug)
    {
      logInform(" CDB: beyond ac");
    }
    return closestPointOnLine(tri_a, tri_c, point, closest_point);
  }

  Eigen::Vector3d bc = tri_c - tri_b;
  Eigen::Vector3d bc_norm = bc.cross(norm);
  if (acorn_closest_debug)
  {
    logInform(" CDB: ab_norm   (%8.4f %8.4f %8.4f) dp=%8.4f >? db=%8.4f",
      bc_norm.x(),
      bc_norm.y(),
      bc_norm.z(),
        bc_norm.dot(point),
        bc_norm.dot(tri_b));
  }
  if (bc_norm.dot(point) > bc_norm.dot(tri_b))
  {
    if (acorn_closest_debug)
    {
      logInform(" CDB: beyond bc");
    }
    return closestPointOnLine(tri_b, tri_c, point, closest_point);
  }

  return abs_dist;
}