コード例 #1
0
ファイル: plane.cpp プロジェクト: NavQ/argos3
 bool CPlane::Intersects(Real& f_t_on_ray,
                         const CRay3& c_ray) {
    /* Ray direction */
    CVector3 cRayDir;
    c_ray.GetDirection(cRayDir);
    /* Calculate f_t_on_ray */
    Real fNumerator = (m_cPosition-c_ray.GetStart()).DotProduct(m_cNormal);
    Real fDenominator = cRayDir.DotProduct(m_cNormal);
    /* Is ray parallel to plane? */
    if(Abs(fDenominator) > 1e-6) {
       /* No, it's not */
       f_t_on_ray = fNumerator / fDenominator / c_ray.GetLength();
       return (f_t_on_ray < 1.0f);
    }
    else {
       /* Yes, it is */
       /* Is ray coincident with the plane? */
       if(Abs(fNumerator) > 1e-6) {
          /* No, the ray is parallel to and far from the plane */
          /* No intersection possible */
          return false;
       }
       else {
          /* Yes, the ray coincides with the plane */
          f_t_on_ray = 0.0f;
          return true;
       }
    }
 }
コード例 #2
0
 Real CFootBotDistanceScannerRotZOnlySensor::CalculateReadingForRay(const CRay3& c_ray,
                                                                    Real f_min_distance) {
    /* Get the closest intersection */
    SEmbodiedEntityIntersectionItem sIntersection;
    if(GetClosestEmbodiedEntityIntersectedByRay(sIntersection,
                                                c_ray,
                                                *m_pcEmbodiedEntity)) {
       if(m_bShowRays) m_pcControllableEntity->AddIntersectionPoint(c_ray, sIntersection.TOnRay);
       /* There is an intersection! */
       Real fDistance = c_ray.GetDistance(sIntersection.TOnRay);
       if(fDistance > f_min_distance) {
          /* The distance is returned in meters, but the reading must be in cm */
          if(m_bShowRays) m_pcControllableEntity->AddCheckedRay(true, c_ray);
          return fDistance * 100.0f;
       }
       else {
          /* The detected intersection was too close */
          if(m_bShowRays) m_pcControllableEntity->AddCheckedRay(true, c_ray);
          return -1.0f;
       }
    }
    else {
       /* No intersection */
       if(m_bShowRays) m_pcControllableEntity->AddCheckedRay(false, c_ray);
       return -2.0f;
    }
 }
コード例 #3
0
CRay3 VoronoiDiagram::getRayBoundedToArena(const CRay3 &ray) const {
    Real startX, startY, endX, endY;
    bool edgeWasClipped = LiangBarsky(
            arenaLimits.GetMin().GetX(),
            arenaLimits.GetMax().GetX(),
            arenaLimits.GetMin().GetY(),
            arenaLimits.GetMax().GetY(),
            ray.GetStart().GetX(), ray.GetStart().GetY(),
            ray.GetEnd().GetX(), ray.GetEnd().GetY(),
            startX, startY, endX, endY);

    if (!edgeWasClipped)
        throw EdgeNotInArea();
    CRay3 boundedRay(CVector3(startX, startY, diagramLiftOnZ),
                     CVector3(endX, endY, diagramLiftOnZ));\
    return boundedRay;
}
コード例 #4
0
/**
 * Check for ray intersection
 */
bool CBulletSphereModel::CheckIntersectionWithRay(Real &f_t_on_ray, const CRay3 &ray) const
{
	CVector3 rayOrigin = ray.GetStart();
	CVector3 rayDirection;
	ray.GetDirection(rayDirection);

	CVector3 sourceToOrigin = rayOrigin - position;
	double sourceToOriginLength = sourceToOrigin.Length();

	double lineDotSourceToOrigin = rayDirection.DotProduct(sourceToOrigin);

	double solutionCheck = pow(lineDotSourceToOrigin, 2);
	solutionCheck -= pow(sourceToOriginLength, 2);
	solutionCheck += pow(entity->GetRadius(), 2);

	if(solutionCheck < 0)
		return false;

	f_t_on_ray = -lineDotSourceToOrigin - sqrt(solutionCheck);
	return true;
}
コード例 #5
0
CRay3 VoronoiDiagram::ToVoronoiEdge(const Edge& edge) const {
    CRay3 voronoiEdge;
    if (edge.is_finite()) {
        voronoiEdge.SetStart(ToVector3(*edge.vertex0()));
        voronoiEdge.SetEnd(ToVector3(*edge.vertex1()));
    }
    else {
        const auto& cell1 = *edge.cell();
        const auto& cell2 = *edge.twin()->cell();
        VoronoiDiagram::Point origin, direction;

        VoronoiDiagram::Point p1 = boostPoints.at(cell1.source_index());
        VoronoiDiagram::Point p2 = boostPoints.at(cell2.source_index());
        p1.set(HORIZONTAL, p1.x()/scaleVectorToMilimeters);
        p1.set(VERTICAL, p1.y()/scaleVectorToMilimeters);
        p2.set(HORIZONTAL, p2.x()/scaleVectorToMilimeters);
        p2.set(VERTICAL, p2.y()/scaleVectorToMilimeters);
        origin.x((p1.x() + p2.x()) * 0.5);
        origin.y((p1.y() + p2.y()) * 0.5);
        direction.x(p1.y() - p2.y());
        direction.y(p2.x() - p1.x());

        Real side = arenaLimits.GetMax().GetX()*2;
        Real koef = side / max(fabs(direction.x()), fabs(direction.y()));
        if (edge.vertex0() == NULL) {
            CVector3 start;
            start.SetX(origin.x() - (direction.x() * koef));
            start.SetY(origin.y() - (direction.y() * koef));
            start.SetZ(diagramLiftOnZ);
            voronoiEdge.SetStart(start);
        } else {
            voronoiEdge.SetStart(ToVector3(*edge.vertex0()));
        }
        if (edge.vertex1() == NULL) {
            CVector3 end;
            end.SetX(origin.x() + direction.x() * koef);
            end.SetY(origin.y() + direction.y() * koef);
            end.SetZ(diagramLiftOnZ);
            voronoiEdge.SetEnd(end);
        } else {
            voronoiEdge.SetEnd(ToVector3(*edge.vertex1()));
        }
    }
    return voronoiEdge;
}
コード例 #6
0
 void CQTOpenGLUserFunctions::DrawRay(const CRay3& c_ray,
                                      const CColor& c_color,
                                      Real f_width) {
    /* Save attributes and current matrix */
    glPushAttrib(GL_LINE_BIT);
    /* Set line attributes */
    glEnable(GL_LINE_SMOOTH);
    glLineWidth(f_width);
    /* Set color */
    SetColor(c_color);
    /* Draw ray */
    glBegin(GL_LINES);
    glVertex3f(c_ray.GetStart().GetX(), c_ray.GetStart().GetY(), c_ray.GetStart().GetZ());
    glVertex3f(c_ray.GetEnd().GetX(), c_ray.GetEnd().GetY(), c_ray.GetEnd().GetZ());
    glEnd();
    /* Restore saved stuff */
    glPopAttrib();
 }
コード例 #7
0
ファイル: cylinder.cpp プロジェクト: NavQ/argos3
 bool CCylinder::Intersects(Real& f_t_on_ray,
                            const CRay3& c_ray) {
    /*
     * This algorithm was adapted from
     * http://www.realtimerendering.com/resources/GraphicsGems/gemsiv/ray_cyl.c
     */
    /* Vector from cylinder base to ray start */
    CVector3 cCylBase2RayStart(c_ray.GetStart());
    cCylBase2RayStart -= m_cBasePos;
    /* Ray direction and length */
    CVector3 cRayDir;
    c_ray.GetDirection(cRayDir);
    Real fRayLen = c_ray.GetLength();
    /* Vector normal to cylinder axis and ray direction */
    CVector3 cNormal(cRayDir);
    cNormal.CrossProduct(m_cAxis);
    Real fNormalLen = cNormal.Length();
    /* Are cylinder axis and ray parallel? */
    if(fNormalLen > 0) {
       /* No, they aren't parallel */
       /* Make normal have length 1 */
       cNormal /= fNormalLen;
       /* Calculate shortest distance between axis and ray
        * by projecting cCylBase2RayStart onto cNormal */
       Real fDist = Abs(cCylBase2RayStart.DotProduct(cNormal));
       /* Is fDist smaller than the cylinder radius? */
       if(fDist > m_fRadius) {
          /* No, it's not, so there can't be any intersection */
          return false;
       }
       /* If we get here, it's because the ray intersects the infinite cylinder */
       /* Create a buffer for the 4 potential intersection points
          (two on the sides, two on the bases) */
       Real fPotentialT[4];
       /* First, calculate the intersection points with the sides */
       /* Calculate the midpoint between the two intersection points */
       CVector3 cVec(cCylBase2RayStart);
       cVec.CrossProduct(m_cAxis);
       Real fMidPointDist = -cVec.DotProduct(cNormal) / fNormalLen;
       /* Calculate the distance between the midpoint and the potential t's */
       cVec = cNormal;
       cVec.CrossProduct(m_cAxis);
       cVec.Normalize();
       Real fDeltaToMidPoint = Abs(Sqrt(Square(m_fRadius) - Square(fDist)) / cRayDir.DotProduct(cVec));
       /* Calculate the potential t's on the infinite surface */
       fPotentialT[0] = (fMidPointDist - fDeltaToMidPoint) / fRayLen;
       fPotentialT[1] = (fMidPointDist + fDeltaToMidPoint) / fRayLen;
       /* Make sure these t's correspond to points within the cylinder bases */
       CVector3 cPoint;
       c_ray.GetPoint(cPoint, fPotentialT[0]);
       if((cPoint - m_cBasePos).DotProduct(m_cAxis) < 0 ||
          (cPoint - (m_cBasePos + m_fHeight * m_cAxis)).DotProduct(m_cAxis) > 0) {
          fPotentialT[0] = -1;
       }
       c_ray.GetPoint(cPoint, fPotentialT[1]);
       if((cPoint - m_cBasePos).DotProduct(m_cAxis) < 0 ||
          (cPoint - (m_cBasePos + m_fHeight * m_cAxis)).DotProduct(m_cAxis) > 0) {
          fPotentialT[1] = -1;
       }
       /* Check whether the ray is contained within the cylinder bases */
       Real fDenominator = cRayDir.DotProduct(m_cAxis);
       /* Is ray parallel to plane? */
       if(Abs(fDenominator) > 1e-6) {
          /* No, it's not parallel */
          fDenominator *= fRayLen;
          /* Bottom base */
          fPotentialT[2] =
             (m_cBasePos - c_ray.GetStart()).DotProduct(m_cAxis) / fDenominator;
          /* Top base */
          fPotentialT[3] =
             (m_cBasePos + m_fHeight * m_cAxis - c_ray.GetStart()).DotProduct(m_cAxis) / fDenominator;
          /* Make sure these t's are within the cylinder surface */
          c_ray.GetPoint(cPoint, fPotentialT[2]);
          CVector3 cDiff = cPoint - m_cBasePos;
          if((cDiff - cDiff.DotProduct(m_cAxis) * m_cAxis).SquareLength() > Square(m_fRadius))
             fPotentialT[2] = -1;
          c_ray.GetPoint(cPoint, fPotentialT[3]);
          cDiff = cPoint - m_cBasePos;
          if((cDiff - cDiff.DotProduct(m_cAxis) * m_cAxis).SquareLength() > Square(m_fRadius))
             fPotentialT[3] = -1;
       }
       else {
          /* Yes, it's parallel - discard the intersections */
          fPotentialT[2] = -1.0;
          fPotentialT[3] = -1.0;
       }
       /* Go through all the potential t's and get the best */
       f_t_on_ray = 2.0;
       for(UInt32 i = 0; i < 4; ++i) {
          if(fPotentialT[i] > 0.0f) {
             f_t_on_ray = Min(f_t_on_ray, fPotentialT[i]);
          }
       }
       /* Return true only if the intersection point is within the ray limits */
       return (f_t_on_ray < 1.0f);
    }
    else {
       /* Yes, ray and axis are parallel */
       /* Projection of cCylBase2RayStart onto the axis */
       Real fProj = cCylBase2RayStart.DotProduct(m_cAxis);
       /* Radial vector */
       CVector3 cRadial(cCylBase2RayStart);
       cRadial -= fProj * m_cAxis;
       Real fDist = cRadial.Length();
       /* Is ray within the cylinder radius? */
       if(fDist > m_fRadius) {
          /* No, it's not */
          return false;
       }
       /* If we get here, it's because the ray might intersect the cylinder bases */
       Real fDenominator = cRayDir.DotProduct(m_cAxis) * fRayLen;
       /* Create a buffer for the 2 potential intersection points */
       Real fPotentialT[2];
       /* Bottom base */
       fPotentialT[0] =
          (m_cBasePos-c_ray.GetStart()).DotProduct(m_cAxis) / fDenominator;
       /* Top base */
       fPotentialT[1] =
          (m_cBasePos + m_fHeight * m_cAxis - c_ray.GetStart()).DotProduct(m_cAxis) / fDenominator;
       /* Make sure these t's are within the cylinder surface */
       CVector3 cPoint;
       c_ray.GetPoint(cPoint, fPotentialT[0]);
       CVector3 cDiff = cPoint - m_cBasePos;
       if((cDiff - cDiff.DotProduct(m_cAxis) * m_cAxis).SquareLength() > Square(m_fRadius))
          fPotentialT[0] = -1;
       c_ray.GetPoint(cPoint, fPotentialT[1]);
       cDiff = cPoint - m_cBasePos;
       if((cDiff - cDiff.DotProduct(m_cAxis) * m_cAxis).SquareLength() > Square(m_fRadius))
          fPotentialT[1] = -1;
       /* Go through all the potential t's and get the best */
       f_t_on_ray = 2.0;
       for(UInt32 i = 0; i < 2; ++i) {
          if(fPotentialT[i] > 0.0f) {
             f_t_on_ray = Min(f_t_on_ray, fPotentialT[i]);
          }
       }
       /* Return true only if the intersection point is within the ray limits */
       return (f_t_on_ray < 1.0f);
    }
 }
コード例 #8
0
 void CFootBotLightRotZOnlySensor::Update() {
    /* Erase readings */
    for(size_t i = 0; i < m_tReadings.size(); ++i) {
       m_tReadings[i].Value = 0.0f;
    }
    /* Get foot-bot orientation */
    CRadians cTmp1, cTmp2, cOrientationZ;
    m_pcEmbodiedEntity->GetOriginAnchor().Orientation.ToEulerAngles(cOrientationZ, cTmp1, cTmp2);
    /* Ray used for scanning the environment for obstacles */
    CRay3 cOcclusionCheckRay;
    cOcclusionCheckRay.SetStart(m_pcEmbodiedEntity->GetOriginAnchor().Position);
    CVector3 cRobotToLight;
    /* Buffer for the angle of the light wrt to the foot-bot */
    CRadians cAngleLightWrtFootbot;
    /* Buffers to contain data about the intersection */
    SEmbodiedEntityIntersectionItem sIntersection;
    /* List of light entities */
    CSpace::TMapPerTypePerId::iterator itLights = m_cSpace.GetEntityMapPerTypePerId().find("light");
    if (itLights != m_cSpace.GetEntityMapPerTypePerId().end()) {
       CSpace::TMapPerType& mapLights = itLights->second;
       /*
     * 1. go through the list of light entities in the scene
     * 2. check if a light is occluded
     * 3. if it isn't, distribute the reading across the sensors
     *    NOTE: the readings are additive
     * 4. go through the sensors and clamp their values
     */
       for(CSpace::TMapPerType::iterator it = mapLights.begin();
           it != mapLights.end();
           ++it) {
          /* Get a reference to the light */
          CLightEntity& cLight = *(any_cast<CLightEntity*>(it->second));
          /* Consider the light only if it has non zero intensity */
          if(cLight.GetIntensity() > 0.0f) {
             /* Set the ray end */
             cOcclusionCheckRay.SetEnd(cLight.GetPosition());
             /* Check occlusion between the foot-bot and the light */
             if(! GetClosestEmbodiedEntityIntersectedByRay(sIntersection,
                                                           cOcclusionCheckRay,
                                                           *m_pcEmbodiedEntity)) {
                /* The light is not occluded */
                if(m_bShowRays) {
                   m_pcControllableEntity->AddCheckedRay(false, cOcclusionCheckRay);
                }
                /* Get the distance between the light and the foot-bot */
                cOcclusionCheckRay.ToVector(cRobotToLight);
                /*
                 * Linearly scale the distance with the light intensity
                 * The greater the intensity, the smaller the distance
                 */
                cRobotToLight /= cLight.GetIntensity();
                /* Get the angle wrt to foot-bot rotation */
                cAngleLightWrtFootbot = cRobotToLight.GetZAngle();
                cAngleLightWrtFootbot -= cOrientationZ;
                /*
                 * Find closest sensor index to point at which ray hits footbot body
                 * Rotate whole body by half a sensor spacing (corresponding to placement of first sensor)
                 * Division says how many sensor spacings there are between first sensor and point at which ray hits footbot body
                 * Increase magnitude of result of division to ensure correct rounding
                 */
                Real fIdx = (cAngleLightWrtFootbot - SENSOR_HALF_SPACING) / SENSOR_SPACING;
                SInt32 nReadingIdx = (fIdx > 0) ? fIdx + 0.5f : fIdx - 0.5f;
                /* Set the actual readings */
                Real fReading = cRobotToLight.Length();
                /*
                 * Take 6 readings before closest sensor and 6 readings after - thus we
                 * process sensors that are with 180 degrees of intersection of light
                 * ray with robot body
                 */
                for(SInt32 nIndexOffset = -6; nIndexOffset < 7; ++nIndexOffset) {
                   UInt32 unIdx = Modulo(nReadingIdx + nIndexOffset, 24);
                   CRadians cAngularDistanceFromOptimalLightReceptionPoint = Abs((cAngleLightWrtFootbot - m_tReadings[unIdx].Angle).SignedNormalize());
                   /*
                    * ComputeReading gives value as if sensor was perfectly in line with
                    * light ray. We then linearly decrease actual reading from 1 (dist
                    * 0) to 0 (dist PI/2)
                    */
                   m_tReadings[unIdx].Value += ComputeReading(fReading) * ScaleReading(cAngularDistanceFromOptimalLightReceptionPoint);
                }
             }
             else {
                /* The ray is occluded */
                if(m_bShowRays) {
                   m_pcControllableEntity->AddCheckedRay(true, cOcclusionCheckRay);
                   m_pcControllableEntity->AddIntersectionPoint(cOcclusionCheckRay, sIntersection.TOnRay);
                }
             }
          }
       }
       /* Apply noise to the sensors */
       if(m_bAddNoise) {
          for(size_t i = 0; i < 24; ++i) {
             m_tReadings[i].Value += m_pcRNG->Uniform(m_cNoiseRange);
          }
       }
       /* Trunc the reading between 0 and 1 */
       for(size_t i = 0; i < 24; ++i) {
          SENSOR_RANGE.TruncValue(m_tReadings[i].Value);
       }
    }
    else {
       /* There are no lights in the environment */
       if(m_bAddNoise) {
          /* Go through the sensors */
          for(UInt32 i = 0; i < m_tReadings.size(); ++i) {
             /* Apply noise to the sensor */
             m_tReadings[i].Value += m_pcRNG->Uniform(m_cNoiseRange);
             /* Trunc the reading between 0 and 1 */
             SENSOR_RANGE.TruncValue(m_tReadings[i].Value);
          }
       }
    }
 }
コード例 #9
0
ファイル: rab_medium.cpp プロジェクト: daneshtarapore/argos3
 void CRABMedium::Update() {
    /* Update positional index of RAB entities */
    m_pcRABEquippedEntityIndex->Update();
    /* Delete routing table */
    for(TRoutingTable::iterator it = m_tRoutingTable.begin();
        it != m_tRoutingTable.end();
        ++it) {
       it->second.clear();
    }
    /* This map contains the pairs that have already been checked */
    unordered_map<ssize_t, std::pair<CRABEquippedEntity*, CRABEquippedEntity*> > mapPairsAlreadyChecked;
    /* Iterator for the above structure */
    unordered_map<ssize_t, std::pair<CRABEquippedEntity*, CRABEquippedEntity*> >::iterator itPair;
    /* Used as test key */
    std::pair<CRABEquippedEntity*, CRABEquippedEntity*> cTestKey;
    /* Used as hash for the test key */
    UInt64 unTestHash;
    /* The ray to use for occlusion checking */
    CRay3 cOcclusionCheckRay;
    /* Buffer for the communicating entities */
    CSet<CRABEquippedEntity*,SEntityComparator> cOtherRABs;
    /* Buffer to store the intersection data */
    SEmbodiedEntityIntersectionItem sIntersectionItem;
    /* The distance between two RABs in line of sight */
    Real fDistance;
    /* Go through the RAB entities */
    for(TRoutingTable::iterator it = m_tRoutingTable.begin();
        it != m_tRoutingTable.end();
        ++it) {
       /* Get a reference to the current RAB entity */
       CRABEquippedEntity& cRAB = *reinterpret_cast<CRABEquippedEntity*>(GetSpace().GetEntityVector()[it->first]);
       /* Initialize the occlusion check ray start to the position of the robot */
       cOcclusionCheckRay.SetStart(cRAB.GetPosition());
       /* For each RAB entity, get the list of RAB entities in range */
       cOtherRABs.clear();
       m_pcRABEquippedEntityIndex->GetEntitiesAt(cOtherRABs, cRAB.GetPosition());
       /* Go through the RAB entities in range */
       for(CSet<CRABEquippedEntity*>::iterator it2 = cOtherRABs.begin();
           it2 != cOtherRABs.end();
           ++it2) {
          /* Get a reference to the RAB entity */
          CRABEquippedEntity& cOtherRAB = **it2;
          /* First, make sure the entities are not the same */
          if(&cRAB != &cOtherRAB) {
             /* Proceed if the pair has not been checked already */
             if(&cRAB < &cOtherRAB) {
                cTestKey.first = &cRAB;
                cTestKey.second = &cOtherRAB;
             }
             else {
                cTestKey.first = &cOtherRAB;
                cTestKey.second = &cRAB;
             }
             unTestHash = HashRABPair(cTestKey);
             itPair = mapPairsAlreadyChecked.find(unTestHash);
             if(itPair == mapPairsAlreadyChecked.end() ||   /* Pair does not exist */
                itPair->second.first != cTestKey.first ||   /* Pair exists, but first RAB involved is different */
                itPair->second.second != cTestKey.second) { /* Pair exists, but second RAB involved is different */
                /* Mark this pair as already checked */
                mapPairsAlreadyChecked[unTestHash] = cTestKey;
                /* Proceed if the message size is compatible */
                if(cRAB.GetMsgSize() == cOtherRAB.GetMsgSize()) {
                   /* Proceed if the two entities are not obstructed by another object */
                   cOcclusionCheckRay.SetEnd(cOtherRAB.GetPosition());
                   if((!m_bCheckOcclusions) ||
                      (!GetClosestEmbodiedEntityIntersectedByRay(sIntersectionItem,
                                                                 cOcclusionCheckRay,
                                                                 cRAB.GetEntityBody())) ||
                      (&cOtherRAB.GetEntityBody() == sIntersectionItem.IntersectedEntity)) {
                      /* If we get here, the two RAB entities are in direct line of sight */
                      /* cRAB can receive cOtherRAB's message if it is in range, and viceversa */
                      /* Calculate square distance */
                      fDistance = cOcclusionCheckRay.GetLength();
                      if(fDistance < cOtherRAB.GetRange()) {
                         /* cRAB receives cOtherRAB's message */
                         m_tRoutingTable[cRAB.GetIndex()].insert(&cOtherRAB);
                      }
                      if(fDistance < cRAB.GetRange()) {
                         /* cOtherRAB receives cRAB's message */
                         m_tRoutingTable[cOtherRAB.GetIndex()].insert(&cRAB);
                      }
                   } // occlusion found?
                } // is msg size the same?
             } // is check necessary?
          } // are entities the same?
       } // for entities in range
    } // for routing table
 }