Esempio n. 1
0
		/**
		 * Sets an end as edge (starting point if none end were defined, ending point otherwise)
		 * @param vertex1 one of the vertices of the intercepted edge 
		 * @param vertex2 one of the vertices of the intercepted edge
		 * @return false if all ends were already defined, true otherwise
		 */
		bool Segment::setEdge(Vertex* vertex1, Vertex* vertex2)
		{
			Vector point1 = vertex1->getPosition();
			Vector point2 = vertex2->getPosition();

			Vector edgeDirection(point2.x - point1.x, point2.y - point1.y, point2.z - point1.z);
			Line edgeLine(edgeDirection, point1);
	
			if(index==0)
			{
				startVertex = vertex1;
				startType = EDGE;
				startPos = line.computeLineIntersection(&edgeLine);
				startDist = line.computePointToPointDistance(startPos);
				middleType = FACE;
				index++;
				return true;		
			}
			else if(index==1)
			{
				endVertex = vertex1;
				endType = EDGE;
				endPos = line.computeLineIntersection(&edgeLine);
				endDist = line.computePointToPointDistance(endPos);
				middleType = FACE;
				index++;
		
				//the ending point distance should be smaller than  starting point distance 
				if(startDist>endDist)
		  			swapEnds();
				return true;
			}
			else
				return false;
		}
bool FvWaypoint::FindClosestPoint(const FvVector3 &kDST3, FvVector3 &kIntersection)
{
	FvVector3 cen = this->Centre();
	FvVector2 src( cen.x, cen.y );
	FvVector2 dst( kDST3.x, kDST3.y );
	FvVector2 movementVector = dst - src;
	FvLine movementLine(src, dst, true);

	for (unsigned int i = 0; i < m_kVertexVector.size(); i++)
	{
		FvVector2 p1 = m_kVertexVector[i].m_kPosition;
		FvVector2 p2 = m_kVertexVector[(i + 1) % m_kVertexVector.size()].m_kPosition;

		float cp1 = movementVector.CrossProduct(p1 - src);
		float cp2 = movementVector.CrossProduct(p2 - src);

		if(cp1 > 0.0f && cp2 < 0.0f)
		{
			FvLine edgeLine(p1, p2, true);
			float p = movementLine.Intersect(edgeLine);
			FvVector2 interv2 = movementLine.Param(p);
			kIntersection.Set( interv2.x, interv2.y, cen.z + 0.1f );
			return true;
		}
	}

	return false;
}
Esempio n. 3
0
    MyVertex::Index GetRepVertex_SPOLY(MyEdge::Index edgeId, SubPolygon* polygon)
    {
        assert(orientation(polygon->supportingPlane(),(polygon->vertex(0))) == ON_ORIENTED_BOUNDARY);
        assert(orientation(polygon->supportingPlane(),(polygon->vertex(1))) == ON_ORIENTED_BOUNDARY);
        assert(orientation(polygon->supportingPlane(),(polygon->vertex(2))) == ON_ORIENTED_BOUNDARY);

        MyEdge& edge = xedge(edgeId);

        // find init point
        int edgeIndexInFace = -1;
        for (int i = 0; i < polygon->degree(); i++)
        {
            if (polygon->edgeId(i) == edgeId)
            {
                edgeIndexInFace = i;
                break;
            }
        }
        assert(edgeIndexInFace != -1);

        MyVertex::Index vIdInPlane;
        XPlane boundPlane, tmpPlane;
        for (int i = 2; i < polygon->degree(); i++)
        {
            vIdInPlane = polygon->vertexId((edgeIndexInFace + i) % polygon->degree());

            // find a bounding plane
            bool flag = false;
            for (auto &neigh : *edge.neighbor)
            {
                if (neigh.type == NeighborInfo::Edge)
                {
                    for (auto fItr = MyEdge::FaceIterator(xedge(neigh.neighborEdgeId), true);
                        fItr; fItr.incrementToTriangle())
                    {
                        assert(fItr.face()->getType() == IPolygon::TRIANGLE);
                        tmpPlane = ((Triangle*)fItr.face())->supportingPlane();
                        if (orientation(tmpPlane, xvertex(vIdInPlane)) != ON_ORIENTED_BOUNDARY)
                        {
                            boundPlane = tmpPlane;
                            flag = true;
                            break;
                        }
                    }
                }
                else
                {
                    assert(neigh.type == NeighborInfo::Face);
                    XPlane tmpPlane = neigh.pTrangle->supportingPlane();
                    if (orientation(tmpPlane, xvertex(vIdInPlane)) != ON_ORIENTED_BOUNDARY)
                    {
                        boundPlane = tmpPlane;
                        break;
                    }
                }
                if (flag) break;
            }
            if (boundPlane.isValid()) break;
        }
        assert(boundPlane.isValid());

        // correct the direction of bounding plane
        XLine edgeLine(polygon->supportingPlane(), boundPlane);
        assert(!polygon->supportingPlane().idEquals(boundPlane));
        int tmpSide = linearOrder(edgeLine, xvertex(polygon->vertexId((edgeIndexInFace + 1) % polygon->degree())),
            xvertex(polygon->vertexId(edgeIndexInFace)));

        assert(tmpSide != 0);
        if (tmpSide < 0)
            boundPlane.inverse();

        // pick a correct rep vertex
        MyVertex::Index repVertexId = INVALID_UINT32;
        for (size_t i = 0; i < polygon->degree(); i++)
        {
            if (orientation(boundPlane, xvertex(polygon->vertexId(i))) == ON_POSITIVE_SIDE)
            {
                repVertexId = polygon->vertexId(i);
                break;
            }
        }
        assert(repVertexId != INVALID_UINT32);
        return repVertexId;
    }
/**
 *	This method fills in the adjacentState reference with
 *	the state for a given adjacency.
 *
 *	@param index			Index of adjacency
 *	@param adjacency	State of adjacency is copied here
 *	@param goal				Goal state
 *
 *	@return True if this is a valid adjacency.
 */
bool WaypointState::getAdjacency(int index,
		WaypointState& adjacency, const WaypointGoalState& goal) const
{
	Vector2 src, dst, p1, p2, movementVector, next;
	float p, cp1, cp2;

	// If this edge on waypoint is not passable, forget it.

	const WaypointSet * pAdjSet = pWaypoint_->adjacentWaypointSet(index);
	if (pWaypoint_->adjacentWaypoint(index) == NULL && pAdjSet == NULL)
		return false;

	// We need 2d vectors for intersection tests.

	src.x = position_.x;
	src.y = position_.z;
	dst.x = goal.position_.x;
	dst.y = goal.position_.z;
	movementVector = dst - src;

	p1 = pWaypoint_->vertexPosition(index);
	p2 = pWaypoint_->vertexPosition((index + 1) % pWaypoint_->vertexCount());

	// move the pts towards each other if we have extra radius
	if (goal.extraRadius() > 0.f)
	{
		const float ger = goal.extraRadius();
		Vector2 edir( p2 - p1 );
		const float elen = edir.length();

		// for now can only pass edges that are long enough
		// (need to only move in conditionally, e.g. if adj to black)
		if (elen < ger * 2.f) return false;

		edir *= ger / elen;
		p1 += edir;
		p2 -= edir;
	}

	cp1 = movementVector.crossProduct(p1 - src);
	cp2 = movementVector.crossProduct(p2 - src);

	// If our desired path takes us through this line segment,
	// find the intersection and use it. Otherwise use the
	// vertex whose crossproduct is closest to zero.

	if(cp1 > 0.0f && cp2 < 0.0f)
	{
		LineEq moveLine(src, dst, true);
		LineEq edgeLine(p1, p2, true);
		p = moveLine.intersect(edgeLine);
		next = moveLine.param(p);
	}
	else if(fabs(cp1) < fabs(cp2))
	{
		next = p1;
	}
	else
	{
		next = p2;
	}

	adjacency.pWPSet_ = (pAdjSet == NULL) ? pWPSet_ : pAdjSet;
	adjacency.waypointID_ = pWaypoint_->adjacentID(index);
	adjacency.pWaypoint_ = pWaypoint_->adjacentWaypoint(index);
	adjacency.position_.x = next.x;
	adjacency.position_.y = position_.y;
	adjacency.position_.z = next.y;
	adjacency.distanceFromParent_ = (position_ - adjacency.position_).length();
	return true;
}