std::vector<unsigned short> GameWorldBase::GetFilteredSeaIDsForAttack(const MapPoint targetPt,
                                                                      const std::vector<unsigned short>& usableSeas,
                                                                      const unsigned char player_attacker) const
{
    // Walk to the flag of the bld/harbor. Important to check because in some locations where the coast is north of the harbor this might be
    // blocked
    const MapPoint flagPt = GetNeighbour(targetPt, Direction::SOUTHEAST);
    std::vector<unsigned short> confirmedSeaIds;
    // Check each possible harbor
    for(unsigned curHbId = 1; curHbId <= GetNumHarborPoints(); ++curHbId)
    {
        const MapPoint harborPt = GetHarborPoint(curHbId);

        if(CalcDistance(harborPt, targetPt) > SEAATTACK_DISTANCE)
            continue;

        // Not attacking this harbor and harbors block?
        if(targetPt != harborPt && GetGGS().getSelection(AddonId::SEA_ATTACK) == 1)
        {
            // Does an enemy harbor exist at current harbor spot? -> Can't attack through this harbor spot
            const auto* hb = GetSpecObj<nobHarborBuilding>(harborPt);
            if(hb && GetPlayer(player_attacker).IsAttackable(hb->GetPlayer()))
                continue;
        }

        for(unsigned z = 0; z < 6; ++z)
        {
            const unsigned short seaId = GetSeaId(curHbId, Direction::fromInt(z));
            if(!seaId)
                continue;
            // sea id is not in compare list or already confirmed? -> skip rest
            if(!helpers::contains(usableSeas, seaId) || helpers::contains(confirmedSeaIds, seaId))
                continue;

            // checks previously tested sea ids to skip pathfinding
            bool previouslytested = false;
            for(unsigned k = 0; k < z; k++)
            {
                if(seaId == GetSeaId(curHbId, Direction::fromInt(k)))
                {
                    previouslytested = true;
                    break;
                }
            }
            if(previouslytested)
                continue;

            // Can figures reach flag from coast
            MapPoint coastalPt = GetCoastalPoint(curHbId, seaId);
            if((flagPt == coastalPt) || FindHumanPath(flagPt, coastalPt, SEAATTACK_DISTANCE) != INVALID_DIR)
            {
                confirmedSeaIds.push_back(seaId);
                // all sea ids confirmed? return without changes
                if(confirmedSeaIds.size() == usableSeas.size())
                    return confirmedSeaIds;
            }
        }
    }
    return confirmedSeaIds;
}
示例#2
0
void IsleOfConquest::OnPlatformTeleport(Player* plr)
{
	LocationVector dest;
	uint32 closest_platform = 0;

	if(plr->GetTeam() == TEAM_ALLIANCE)
	{
		for (uint32 i = 0; i < 6; i++)
		{
			float distance = CalcDistance(plr->GetPositionX(),
				plr->GetPositionY(), plr->GetPositionZ(),
				iocTransporterDestination[i][0],
				iocTransporterDestination[i][1],
				iocTransporterDestination[i][2]);
			if (distance < 75 && distance > 10)
			{
				closest_platform = i;
				break;
			}
		}
		dest.ChangeCoords(iocTransporterDestination[closest_platform][0],
			iocTransporterDestination[closest_platform][1],
			iocTransporterDestination[closest_platform][2],
			iocTransporterDestination[closest_platform][3]);
	}
	else		// HORDE
	{
		for (uint32 i = 6; i < 12; i++)
		{
			float distance = CalcDistance(plr->GetPositionX(),
				plr->GetPositionY(), plr->GetPositionZ(),
				iocTransporterDestination[i][0],
				iocTransporterDestination[i][1],
				iocTransporterDestination[i][2]);
			if (distance < 75 && distance > 10)
			{
				closest_platform = i;
				break;
			}
		}
		dest.ChangeCoords(iocTransporterDestination[closest_platform][0],
			iocTransporterDestination[closest_platform][1],
			iocTransporterDestination[closest_platform][2],
			iocTransporterDestination[closest_platform][3]);
	}
	plr->SafeTeleport(plr->GetMapId(), plr->GetInstanceID(), dest);
}
std::vector<unsigned> GameWorldBase::GetUsableTargetHarborsForAttack(const MapPoint targetPt, std::vector<bool>& use_seas,
                                                                     const unsigned char player_attacker) const
{
    // Walk to the flag of the bld/harbor. Important to check because in some locations where the coast is north of the harbor this might be
    // blocked
    const MapPoint flagPt = GetNeighbour(targetPt, Direction::SOUTHEAST);
    std::vector<unsigned> harbor_points;
    // Check each possible harbor
    for(unsigned curHbId = 1; curHbId <= GetNumHarborPoints(); ++curHbId)
    {
        const MapPoint harborPt = GetHarborPoint(curHbId);

        if(CalcDistance(harborPt, targetPt) > SEAATTACK_DISTANCE)
            continue;

        // Not attacking this harbor and harbors block?
        if(targetPt != harborPt && GetGGS().getSelection(AddonId::SEA_ATTACK) == 1)
        {
            // Does an enemy harbor exist at current harbor spot? -> Can't attack through this harbor spot
            const auto* hb = GetSpecObj<nobHarborBuilding>(harborPt);
            if(hb && GetPlayer(player_attacker).IsAttackable(hb->GetPlayer()))
                continue;
        }

        // add seaIds from which we can actually attack the harbor
        bool harborinlist = false;
        for(unsigned z = 0; z < 6; ++z)
        {
            const unsigned short seaId = GetSeaId(curHbId, Direction::fromInt(z));
            if(!seaId)
                continue;
            // checks previously tested sea ids to skip pathfinding
            bool previouslytested = false;
            for(unsigned k = 0; k < z; k++)
            {
                if(seaId == GetSeaId(curHbId, Direction::fromInt(k)))
                {
                    previouslytested = true;
                    break;
                }
            }
            if(previouslytested)
                continue;

            // Can figures reach flag from coast
            const MapPoint coastalPt = GetCoastalPoint(curHbId, seaId);
            if((flagPt == coastalPt) || FindHumanPath(flagPt, coastalPt, SEAATTACK_DISTANCE) != INVALID_DIR)
            {
                use_seas.at(seaId - 1) = true;
                if(!harborinlist)
                {
                    harbor_points.push_back(curHbId);
                    harborinlist = true;
                }
            }
        }
    }
    return harbor_points;
}
void KMeans::AddToMinimalDistanceCluster(Point* point)
{
	int clusterIndex = 0;
	double minDist = CalcDistance(*Clusters->begin(), point);
	std::vector<Cluster*>::iterator iter;
	Cluster* c1;
	Cluster* closest = *Clusters->begin();
	for (iter = Clusters->begin(); iter < Clusters->end(); iter++)
	{
		c1 = (Cluster*)*iter;
		double dist = CalcDistance(c1, point);
		if (dist < minDist)
		{
			closest = c1;
			minDist = dist;
		}
	}
	closest->AddPoint(point);
}
示例#5
0
void ObjectDrawList::Add(const ViewParams& Params, LTObject *pObject, DrawObjectFn fn) 
{	
	if (!g_CV_DrawSorted.m_Val)
	{
		fn(Params, pObject);
		return;
	}

	// Add it to the queue
	m_aObjects.push(ObjectDrawer(pObject, fn, CalcDistance(pObject, Params)));
}
示例#6
0
DWORD CBaseFaceGroup::BuildPrjLightMesh(CIBCache* pIBCache,DWORD dwLightIndex,VECTOR3* pv3LightPos,BOOL bCameraUpdate)
{


    pIBCache->Hit();
    if (!m_pPrjMeshDesc->prjLightMeshList[dwLightIndex].pIBPrjLight)
        goto lb_update;

    if (bCameraUpdate)
    {
        // 카메라 위치가 변경되면 무조건 업데이트.
        goto lb_update_and_free;
    }

    float	fDist;
    fDist = CalcDistance(pv3LightPos,&m_pPrjMeshDesc->prjLightMeshList[dwLightIndex].v3LightPosPrv);
    if (fDist > MIN_UNIT*2.0f)
        goto lb_update_and_free;

    /*

    // 라이트 위치가 변경되면 업데이트
    if (pv3LightPos->x != m_pPrjMeshDesc->prjLightMeshList[dwLightIndex].v3LightPosPrv.x)
    	goto lb_update_and_free;

    if (pv3LightPos->y != m_pPrjMeshDesc->prjLightMeshList[dwLightIndex].v3LightPosPrv.y)
    	goto lb_update_and_free;

    if (pv3LightPos->z != m_pPrjMeshDesc->prjLightMeshList[dwLightIndex].v3LightPosPrv.z)
    	goto lb_update_and_free;
    */
    goto lb_return;

lb_update_and_free:
    pIBCache->FreeIB(m_pPrjMeshDesc->prjLightMeshList[dwLightIndex].pIBPrjLight);

lb_update:
    m_pPrjMeshDesc->prjLightMeshList[dwLightIndex].v3LightPosPrv = *pv3LightPos;

    if (!pIBCache->GetIB(&m_pPrjMeshDesc->prjLightMeshList[dwLightIndex].piUseCount,m_dwCulledWithCameraFacesNum*3,&m_pPrjMeshDesc->prjLightMeshList[dwLightIndex].pIBPrjLight,(void*)this))
    {
        m_pPrjMeshDesc->prjLightMeshList[dwLightIndex].dwCulledWithLightFacesNum = 0;
        goto lb_return;
    }

    m_pPrjMeshDesc->prjLightMeshList[dwLightIndex].dwCulledWithLightFacesNum =
        CullFaceListWithLight(m_pPrjMeshDesc->prjLightMeshList[dwLightIndex].pIBPrjLight,pv3LightPos);

    (*m_pPrjMeshDesc->prjLightMeshList[dwLightIndex].piUseCount)++;

lb_return:
    return m_pPrjMeshDesc->prjLightMeshList[dwLightIndex].dwCulledWithLightFacesNum;

}
/// returns true when a harborpoint is in SEAATTACK_DISTANCE for figures!
bool GameWorldBase::IsAHarborInSeaAttackDistance(const MapPoint pos) const
{
    for(unsigned i = 1; i <= GetNumHarborPoints(); ++i)
    {
        if(CalcDistance(pos, GetHarborPoint(i)) < SEAATTACK_DISTANCE)
        {
            if(FindHumanPath(pos, GetHarborPoint(i), SEAATTACK_DISTANCE) != 0xff)
                return true;
        }
    }
    return false;
}
示例#8
0
fixed
XContestTriangle::CalcScore() const
{
  // DHV-XC: 2.0 or 1.75 points per km for FAI vs non-FAI triangle
  // XContest: 1.4 or 1.2 points per km for FAI vs non-FAI triangle

  const fixed score_factor = is_dhv?
    (is_fai? fixed(0.002): fixed(0.00175))
    :(is_fai? fixed(0.0014): fixed(0.0012));

  return ApplyHandicap(CalcDistance()*score_factor);
}
示例#9
0
/// returns true when a harborpoint is in SEAATTACK_DISTANCE for figures!
bool GameWorldBase::IsAHarborInSeaAttackDistance(const Point<MapCoord> pos) const
{
	for(unsigned i = 1;i<harbor_pos.size();++i) //poc: harbor dummy at spot 0 ask Oliverr why 
	{
		if(CalcDistance(pos.x,pos.y,harbor_pos[i].x,harbor_pos[i].y)<SEAATTACK_DISTANCE)
		{
			if(FindHumanPath(pos.x,pos.y,harbor_pos[i].x,harbor_pos[i].y,SEAATTACK_DISTANCE!=0xff))
				return true;
		}
	}		
	return false;
}
示例#10
0
void CderScorer::computeCD(const sent_t& cand, const sent_t& ref,
                           vector<ScoreStatsType>& stats) const
{
  int I = cand.size() + 1; // Number of inter-words positions in candidate sentence
  int L = ref.size() + 1; // Number of inter-words positions in reference sentence

  int l = 0;
  // row[i] stores cost of cheapest path from (0,0) to (i,l) in CDER aligment grid.
  vector<int>* row = new vector<int>(I);

  // Initialization of first row
  for (int i = 0; i < I; ++i) (*row)[i] = i;

  // For CDER metric, the initialization is different
  if (m_allowed_long_jumps) {
    for (int i = 1; i < I; ++i) (*row)[i] = 1;
  }

  // Calculating costs for next row using costs from the previous row.
  while (++l < L) {
    vector<int>* nextRow = new vector<int>(I);
    for (int i = 0; i < I; ++i) {
      vector<int> possibleCosts;
      if (i > 0) {
        possibleCosts.push_back((*nextRow)[i-1] + 1); // Deletion
        possibleCosts.push_back((*row)[i-1] + CalcDistance(ref[l-1], cand[i-1])); // Substitution/Identity
      }
      possibleCosts.push_back((*row)[i] + 1); // Insertion
      (*nextRow)[i] = *min_element(possibleCosts.begin(), possibleCosts.end());
    }

    if (m_allowed_long_jumps) {
      // Cost of LongJumps is the same for all in the row
      int LJ = 1 + *min_element(nextRow->begin(), nextRow->end());

      for (int i = 0; i < I; ++i) {
        (*nextRow)[i] = min((*nextRow)[i], LJ); // LongJumps
      }
    }

    delete row;
    row = nextRow;
  }

  stats.resize(2);
  stats[0] = *(row->rbegin());  // CD distance is the cost of path from (0,0) to (I,L)
  stats[1] = ref.size();

  delete row;
}
示例#11
0
/// returns all sea_ids from which a given building can be attacked by sea
void GameWorldBase::GetValidSeaIDsAroundMilitaryBuildingForAttack(const MapCoord x,const MapCoord y, std::vector<bool> * use_seas, const unsigned char player_attacker,std::vector<unsigned>*harbor_points) const
{
	assert(use_seas);
	// Nach Hafenpunkten in der Nähe des angegriffenen Gebäudes suchen
	// Alle unsere Häfen durchgehen
	for(unsigned i = 1;i<harbor_pos.size();++i)

	{
		MapCoord harbor_x = harbor_pos[i].x, harbor_y = harbor_pos[i].y;
		
		if(CalcDistance(harbor_x,harbor_y,x,y) <= SEAATTACK_DISTANCE)
		{
			//target isnt the harbor pos AND there is an enemy harbor? -> done for this harbor pos
			const nobHarborBuilding *hb=GetSpecObj<nobHarborBuilding>(x,y);
			if(!(x == harbor_x && y == harbor_y) && hb && players->getElement(player_attacker)->IsPlayerAttackable(GetNode(x,y).owner-1))
			{
				continue;
			}
			else
			{
				// Ist Ziel der Hafenspot? -> add sea_ids
				if(x == harbor_x && y == harbor_y)
				{
					harbor_points->push_back(i);
					unsigned short sea_ids[6];
					GetSeaIDs(i,sea_ids);
					for(unsigned z = 0;z<6;++z)
					{
						if(sea_ids[z])
							use_seas->at(sea_ids[z]) = true;
					}
				}			
				//so our target building is in range of a free or allied harbor pos but not the harborspot - now lets see if we can findhumanpath
				else if(FindHumanPath(x,y,harbor_x,harbor_y,SEAATTACK_DISTANCE) != 0xff)				
				{
					harbor_points->push_back(i);
					unsigned short sea_ids[6];
					GetSeaIDs(i,sea_ids);
					for(unsigned z = 0;z<6;++z)
					{
						if(sea_ids[z])
							use_seas->at(sea_ids[z]) = true;
					}
				}
			}
		}
	}

}
示例#12
0
int parsingContours(vector<contour_t> &found_contures, kalmanCont &tracked_object) {
    double max = max_dist_to_pars;
    double distance;
    int conture_id = -1;


    for (int i = 0; i < found_contures.size(); i++) {
        distance = CalcDistance(tracked_object.get_kalman_x_pos(), found_contures[i].mu.m10 / found_contures[i].mu.m00,
                                tracked_object.get_kalman_y_pos(), found_contures[i].mu.m01 / found_contures[i].mu.m00);
        distance = distance + 20 * found_contures[i].candidate_object.size();
        if (distance < max && !found_contures[i].contour_use) {
            max = distance;
            conture_id = i ;
        }
    }

    return  conture_id;
}
示例#13
0
///=====================================================
/// 
///=====================================================
void WaveEmitter::Update(double deltaSeconds){
	double currentTime = GetCurrentSeconds();

	//update existing particles
	for (Particles::iterator particleIter = m_particles.begin(); particleIter != m_particles.end();){
		Particle* particle = *particleIter;

		//delete expired particles
		if (particle->m_expirationTime < currentTime){
			delete particle;
			particleIter = m_particles.erase(particleIter);
			continue;
		}


		//COLORFUL SPIRAL LOL
		Vec2 tempVel(particle->m_velocity.x, particle->m_velocity.z);
		tempVel.RotateDegrees(32.0f * (float)deltaSeconds * 90.0f / (float)m_duration);
		particle->m_velocity = Vec3(tempVel.x, 0.0f, tempVel.y);

		Vec2 tempPos(particle->m_position.x, particle->m_position.z);
		tempPos.RotateDegrees(32.0f * (float)deltaSeconds * 90.0f / (float)m_duration);
		particle->m_position = Vec3(tempPos.x, particle->m_position.y, tempPos.y);

		if (GetRandomFloatInRange(0.0f, 1.0f) > cos(currentTime)){
			particle->m_color.r -= (unsigned char)GetRandomIntInRange(0, 3);
			particle->m_color.g -= (unsigned char)GetRandomIntInRange(2, 6);
			particle->m_color.b += (unsigned char)GetRandomIntInRange(1, 9);
		}

		particle->m_position.y = m_position.y + m_waveHeight * cos((CalcDistance(Vec2(m_position.x, m_position.z), Vec2(particle->m_position.x, particle->m_position.z)) - (float)currentTime) * m_waveSpeed);
		particle->Update(deltaSeconds);
		++particleIter;
	}

	//add new particles
	m_timeSinceParticleEmission += deltaSeconds;
	if (m_timeSinceParticleEmission >= m_timeBetweenParticleEmissions){
		AddParticles();
		m_timeSinceParticleEmission -= m_timeBetweenParticleEmissions;
	}
}
/// Liefert Hafenpunkte im Umkreis von einem bestimmten Militärgebäude
std::vector<unsigned> GameWorldBase::GetHarborPointsAroundMilitaryBuilding(const MapPoint pt) const
{
    std::vector<unsigned> harbor_points;
    // Nach Hafenpunkten in der Nähe des angegriffenen Gebäudes suchen
    // Alle unsere Häfen durchgehen
    for(unsigned i = 1; i <= GetNumHarborPoints(); ++i)
    {
        const MapPoint harborPt = GetHarborPoint(i);

        if(CalcDistance(harborPt, pt) <= SEAATTACK_DISTANCE)
        {
            // Wird ein Weg vom Militärgebäude zum Hafen gefunden bzw. Ziel = Hafen?
            if(pt == harborPt)
                harbor_points.push_back(i);
            else if(FindHumanPath(pt, harborPt, SEAATTACK_DISTANCE) != 0xff)
                harbor_points.push_back(i);
        }
    }
    return harbor_points;
}
示例#15
0
void loadValidCounureToObject(vector<contour_t> &found_contures, vector<kalmanCont> &tracked_object){
    double max = max_dist_to_pars;
    double distance;

    for (size_t k = 0; k < tracked_objects.size(); k++) {
        for (size_t i = 0; i < found_contures.size(); i++) {
            distance = CalcDistance(tracked_object[k].get_kalman_x_pos(),
                                    found_contures[i].mu.m10 / found_contures[i].mu.m00,
                                    tracked_object[k].get_kalman_y_pos(),
                                    found_contures[i].mu.m01 / found_contures[i].mu.m00);

            if (distance < max) {
                tracked_object[k].push_selected_conture(found_contures[i].id, distance);

            }
        }
        tracked_object[k].sort_conture_low_high();

    }
}
示例#16
0
/// Liefert Hafenpunkte im Umkreis von einem bestimmten Militärgebäude
void GameWorldBase::GetHarborPointsAroundMilitaryBuilding(const MapCoord x, const MapCoord y, std::vector<unsigned> * harbor_points) const
{
	assert(harbor_points);
	

	// Nach Hafenpunkten in der Nähe des angegriffenen Gebäudes suchen
	// Alle unsere Häfen durchgehen
	for(unsigned i = 1;i<harbor_pos.size();++i)

	{
		MapCoord harbor_x = harbor_pos[i].x, harbor_y = harbor_pos[i].y;
		
		if(CalcDistance(harbor_x,harbor_y,x,y) <= SEAATTACK_DISTANCE)
		{
			// Wird ein Weg vom Militärgebäude zum Hafen gefunden bzw. Ziel = Hafen?
			if(x == harbor_x && y == harbor_y)
				harbor_points->push_back(i);
			else if(FindHumanPath(x,y,harbor_x,harbor_y,SEAATTACK_DISTANCE) != 0xff)
				harbor_points->push_back(i);
		}
	}
}
示例#17
0
/*****************************************************************************
  Function name: CalcWeights()

  Purpose      : Calculate interpolation weights to interpolate the
                 meteorological data from the various stations for every
                 individual pixel

  Required     :
    METLOCATION *Station - Location of meteorological stations
    int NStats           - Number of meteorological stations
    int NX               - Number of pixels in East - West direction
    int NY               - Number of pixels in North - South direction
    uchar ** BasinMask   - BasinMask
    uchar ***WeightArray - 3D array with interpolation weights
  
  Returns      :  void

  Modifies     :
    The values stored at the addresses pointed to by WeightArray (i.e. it
    calculates the weights and stores them)

  Comments     :
*****************************************************************************/
void CalcWeights(METLOCATION * Station, int NStats, int NX, int NY,
		 uchar ** BasinMask, uchar **** WeightArray,
		 OPTIONSTRUCT * Options)
{
  double *Weights;		/* Array with weights for all stations */
  double *Distance;		/* Array with distances to all stations */
  double *InvDist2;		/* Array with inverse distance squared */
  double Denominator;		/* Sum of 1/Distance^2 */
  double mindistance;
  double avgdistance;
  double tempdistance;
  double cr, crt;
  int totalweight;
  int y;			/* Counter for rows */
  int x;			/* Counter for columns */
  int i, j;			/* Counter for stations */
  int CurrentStation;		/* Station at current location (if any) */
  int *stationid;		/* index array for sorted list of station distances */
  int *stat;
  int tempid;
  int closest;
  int crstat;
  COORD Loc;			/* Location of current point */

  /* Allocate memory for a 3 dimensional array */

  if (DEBUG)
    printf("Calculating interpolation weights for %d stations\n", NStats);

  if (!((*WeightArray) = (uchar ***) calloc(NY, sizeof(uchar **))))
    ReportError("CalcWeights()", 1);

  for (y = 0; y < NY; y++)
    if (!((*WeightArray)[y] = (uchar **) calloc(NX, sizeof(uchar *))))
      ReportError("CalcWeights()", 1);

  for (y = 0; y < NY; y++)
    for (x = 0; x < NX; x++)
      if (!((*WeightArray)[y][x] = (uchar *) calloc(NStats, sizeof(uchar))))
	ReportError("CalcWeights()", 1);

  /* Allocate memory for the array that will contain weights, and the array for
     the distances to each of the towers, and the inverse distance squared */

  if (!(Weights = (double *) calloc(NStats, sizeof(double))))
    ReportError("CalcWeights()", 1);

  if (!(Distance = (double *) calloc(NStats, sizeof(double))))
    ReportError("CalcWeights()", 1);

  if (!(InvDist2 = (double *) calloc(NStats, sizeof(double))))
    ReportError("CalcWeights()", 1);

  if (!(stationid = (int *) calloc(NStats, sizeof(int))))
    ReportError("CalcWeights()", 1);
  if (!(stat = (int *) calloc(NStats + 1, sizeof(int))))
    ReportError("CalcWeights()", 1);

  /* Calculate the weights for each location that is inside the basin mask */
  /* note stations themselves can be outside the mask */
  /* this first scheme is an inverse distance squared scheme */

  if (Options->Interpolation == INVDIST) {
    for (y = 0; y < NY; y++) {
      Loc.N = y;
      for (x = 0; x < NX; x++) {
	Loc.E = x;
	if (INBASIN(BasinMask[y][x])) {
	  if (IsStationLocation(&Loc, NStats, Station, &CurrentStation)) {
	    for (i = 0; i < NStats; i++) {
	      if (i == CurrentStation)
		(*WeightArray)[y][x][i] = MAXUCHAR;
	      else
		(*WeightArray)[y][x][i] = 0;
	    }
	  }
	  else {
	    for (i = 0, Denominator = 0; i < NStats; i++) {
	      Distance[i] = CalcDistance(&(Station[i].Loc), &Loc);
	      InvDist2[i] = 1 / (Distance[i] * Distance[i]);
	      Denominator += InvDist2[i];
	    }
	    for (i = 0; i < NStats; i++) {
	      (*WeightArray)[y][x][i] =
		(uchar) Round(InvDist2[i] / Denominator * MAXUCHAR);
	    }
	  }
	}
	else {
	  for (i = 0; i < NStats; i++)
	    (*WeightArray)[y][x][i] = 0;
	}
      }
    }
  }
  if (Options->Interpolation == NEAREST) {

    /* this next scheme is a nearest station */
    printf("Number of stations is %d \n", NStats);

    for (y = 0; y < NY; y++) {
      Loc.N = y;
      for (x = 0; x < NX; x++) {
	Loc.E = x;
	if (INBASIN(BasinMask[y][x])) {	/*we are inside the basin mask */
	  /* find the distance to nearest station */
	  mindistance = DHSVM_HUGE;
	  avgdistance = 0.0;
	  for (i = 0; i < NStats; i++) {
	    Distance[i] = CalcDistance(&(Station[i].Loc), &Loc);
	    avgdistance += Distance[i] / ((double) NStats);
	    if (Distance[i] < mindistance) {
	      mindistance = Distance[i];
	      closest = i;
	    }
	  }
	  /* got closest station */

	  for (i = 0; i < NStats; i++) {
	    if (i == closest)
	      (*WeightArray)[y][x][i] = MAXUCHAR;
	    else
	      (*WeightArray)[y][x][i] = 0;
	  }

	}			/* done in basin mask */
	else {
	  for (i = 0; i < NStats; i++)
	    (*WeightArray)[y][x][i] = 0;
	}
      }
    }
  }

  if (Options->Interpolation == VARCRESS) {

    /* this next scheme is a variable radius cressman */
    /* find the distance to the nearest station */
    /* make a decision based on the maximum allowable radius, cr */
    /* and the distance to the closest station */
    /* while limiting the number of interpolation stations to three */
    cr = (double) Options->CressRadius;
    if (cr < 2)
      ReportError("CalcWeights.c", 42);
    crstat = Options->CressStations;
    if (crstat < 2)
      ReportError("CalcWeights.c", 42);
    for (y = 0; y < NY; y++) {
      Loc.N = y;
      for (x = 0; x < NX; x++) {
	Loc.E = x;
	if (INBASIN(BasinMask[y][x])) {	/*we are inside the basin mask */
	  /* find the distance to nearest station */
	  for (i = 0; i < NStats; i++) {
	    Distance[i] = CalcDistance(&(Station[i].Loc), &Loc);
	    stationid[i] = i;
	  }
	  /* got distances for each station */
	  /* now sort the list by distance */
	  for (i = 0; i < NStats; i++) {
	    for (j = 0; j < NStats; j++) {
	      if (Distance[j] > Distance[i]) {
		tempdistance = Distance[i];
		tempid = stationid[i];
		Distance[i] = Distance[j];
		stationid[i] = stationid[j];
		Distance[j] = tempdistance;
		stationid[j] = tempid;
	      }
	    }
	  }

	  crt = Distance[0] * 2.0;
	  if (crt < 1.0)
	    crt = 1.0;
	  for (i = 0, Denominator = 0; i < NStats; i++) {
	    if (i < crstat && Distance[i] < crt) {
	      InvDist2[i] =
		(crt * crt - Distance[i] * Distance[i]) /
		(crt * crt + Distance[i] * Distance[i]);
	      Denominator += InvDist2[i];
	    }
	    else
	      InvDist2[i] = 0.0;
	  }

	  for (i = 0; i < NStats; i++)
	    (*WeightArray)[y][x][stationid[i]] =
	      (uchar) Round(InvDist2[i] / Denominator * MAXUCHAR);

	  /*at this point all weights have been assigned to one or more stations */

	}
      }
    }
  }

  /*check that all weights add up to MAXUCHAR */
  /* and output some stats on the interpolation field */

  for (i = 0; i <= NStats; i++)
    stat[i] = 0;
  for (i = 0; i < NStats; i++)
    stationid[i] = 0;

  printf("\nChecking interpolation weights\n");
  printf("Sum should be 255 for all pixels \n");
  printf("Some error is expected due to roundoff \n");
  printf("Errors greater than +/- 2 Percent are: \n");

  for (y = 0; y < NY; y++) {
    for (x = 0; x < NX; x++) {
      if (INBASIN(BasinMask[y][x])) {	/*we are inside the basin mask */
	tempid = 0;
	totalweight = 0;

	for (i = 0; i < NStats; i++) {
	  totalweight += (int) (*WeightArray)[y][x][i];
	  if ((*WeightArray)[y][x][i] > 0) {
	    tempid += 1;
	    stationid[i] = 1;
	  }
	}

	if (totalweight < 250 || totalweight > 260)
	{
	  printf("error in interpolation weight at pixel y %d x %d : %d \n", y,
		 x, totalweight);
	  assert(FALSE);
	}
	stat[tempid] += 1;
      }

    }
  }
  for (i = 0; i <= NStats; i++)
    if (stat[i] > 0)
      printf("this many pixels %d are linked to %d met stations \n", stat[i],
	     i);

  for (i = 0; i < NStats; i++)
    if (stationid[i] > 0)
      printf("Station: %s used in interpolation \n", Station[i].Name);

  /* Free memory */

  free(Weights);
  free(Distance);
  free(InvDist2);
  free(stationid);
  free(stat);
}
示例#18
0
DWORD CBaseFaceGroup::BuildPrjShadowMesh(CIBCache* pIBCache,DWORD dwShadowIndex,VECTOR3* pv3ShadowLightPos,BOUNDING_SPHERE* pShadowSenderPos,BOOL bCameraUpdate)
{

    pIBCache->Hit();
    if (!m_pPrjMeshDesc->prjShadowMeshList[dwShadowIndex].pIBPrjShadow)
        goto lb_update;


    IBCACHE_ITEM*	pDelItem;
    pDelItem = (IBCACHE_ITEM*)m_pPrjMeshDesc->prjShadowMeshList[dwShadowIndex].pIBPrjShadow;
//	if (pDelItem->dwIndexInAllocatedTable == 0xcccccccc)
//		__asm int 3


    if (bCameraUpdate)
        goto lb_update_and_free;

    // 라이트 위치가 변경되면 업데이트
    float	fDist;
    fDist = CalcDistance(pv3ShadowLightPos,&m_pPrjMeshDesc->prjShadowMeshList[dwShadowIndex].v3ShadowLightPos);
    if (fDist > MIN_UNIT*2.0f)
        goto lb_update_and_free;

    fDist = CalcDistance(&pShadowSenderPos->v3Point,&m_pPrjMeshDesc->prjShadowMeshList[dwShadowIndex].bpShadowSenderPrv.v3Point);
    if (fDist > MIN_UNIT*2.0f)
        goto lb_update_and_free;

    /*
    if (pv3ShadowLightPos->x != m_pPrjMeshDesc->prjShadowMeshList[dwShadowIndex].v3ShadowLightPos.x)
    	goto lb_update_and_free;

    if (pv3ShadowLightPos->y != m_pPrjMeshDesc->prjShadowMeshList[dwShadowIndex].v3ShadowLightPos.y)
    	goto lb_update_and_free;

    if (pv3ShadowLightPos->z != m_pPrjMeshDesc->prjShadowMeshList[dwShadowIndex].v3ShadowLightPos.z)
    	goto lb_update_and_free;

    if (pShadowSenderPos->v3Point.x != m_pPrjMeshDesc->prjShadowMeshList[dwShadowIndex].bpShadowSenderPrv.v3Point.x)
    	goto lb_update_and_free;

    if (pShadowSenderPos->v3Point.y != m_pPrjMeshDesc->prjShadowMeshList[dwShadowIndex].bpShadowSenderPrv.v3Point.y)
    	goto lb_update_and_free;

    if (pShadowSenderPos->v3Point.z != m_pPrjMeshDesc->prjShadowMeshList[dwShadowIndex].bpShadowSenderPrv.v3Point.z)
    	goto lb_update_and_free;

    if (pShadowSenderPos->fRs != m_pPrjMeshDesc->prjShadowMeshList[dwShadowIndex].bpShadowSenderPrv.fRs)
    	goto lb_update_and_free;
    */
    goto lb_return;

lb_update_and_free:

    pIBCache->FreeIB(m_pPrjMeshDesc->prjShadowMeshList[dwShadowIndex].pIBPrjShadow);


lb_update:
    m_pPrjMeshDesc->prjShadowMeshList[dwShadowIndex].v3ShadowLightPos = *pv3ShadowLightPos;
    m_pPrjMeshDesc->prjShadowMeshList[dwShadowIndex].bpShadowSenderPrv = *pShadowSenderPos;

    if (!pIBCache->GetIB(&m_pPrjMeshDesc->prjShadowMeshList[dwShadowIndex].piUseCount,m_dwCulledWithCameraFacesNum*3,&m_pPrjMeshDesc->prjShadowMeshList[dwShadowIndex].pIBPrjShadow,(void*)this))
    {
        m_pPrjMeshDesc->prjShadowMeshList[dwShadowIndex].dwCulledWithShadowLightFacesNum = 0;
        goto lb_return;
    }

    m_pPrjMeshDesc->prjShadowMeshList[dwShadowIndex].dwCulledWithShadowLightFacesNum =
        CullFaceListWithShadowLight(m_pPrjMeshDesc->prjShadowMeshList[dwShadowIndex].pIBPrjShadow,pv3ShadowLightPos,pShadowSenderPos);

    (*m_pPrjMeshDesc->prjShadowMeshList[dwShadowIndex].piUseCount)++;

lb_return:
    return m_pPrjMeshDesc->prjShadowMeshList[dwShadowIndex].dwCulledWithShadowLightFacesNum;

}
double CPositioningBasicAlgorithm::CalcDistanceFromSensor(SPosition SensorPosition) const
{
	return CalcDistance(SensorPosition.x, SensorPosition.y, m_LastPosition.x, m_LastPosition.y);
}
示例#20
0
///==========================================================================================================================================
/// Accessors
///==========================================================================================================================================
float LineSegment3D::CalcLength() const{
	return CalcDistance(startPoint, endPoint);
}
示例#21
0
 /** 
  * Distance function for edges
  * 
  * @param s1 Origin node
  * @param s2 Destination node
  * 
  * @return Distance (flat) from origin to destination
  */
 gcc_pure
 unsigned CalcDistance(const ScanTaskPoint s1, const ScanTaskPoint s2) const {
   return CalcDistance(s1, GetPoint(s2));
 }
示例#22
0
/// Wegfinden ( A* ),  O(v lg v) --> Wegfindung auf allgemeinen Terrain (ohne Straßen),  für Wegbau und frei herumlaufende Berufe
bool GameWorldBase::FindPathOnRoads(const noRoadNode* const start,  const noRoadNode* const goal, 
                                    const bool ware_mode,  unsigned* length, 
                                    unsigned char* first_dir,   MapPoint* next_harbor, 
                                    const RoadSegment* const forbidden,  const bool record,  unsigned max) const
{
    // Aus Replay lesen?
    if(GAMECLIENT.ArePathfindingResultsAvailable() && record)
    {
        unsigned char dir;
        if(GAMECLIENT.ReadPathfindingResult(&dir,  length,  next_harbor))
        {
            if(first_dir) *first_dir = dir;
            return (dir != 0xff);
        }
    }

    // Irgendwelche Null-Anfänge oder Ziele? --> Kein Weg
    if(!start || !goal)
    {
        if(record)
            GAMECLIENT.AddPathfindingResult(0xff,  length,  next_harbor);
        return false;
    }

    // increase current_visit_on_roads,  so we don't have to clear the visited-states at every run
    current_visit_on_roads++;

    // if the counter reaches its maxium,  tidy up
    if (current_visit_on_roads == std::numeric_limits<unsigned>::max())
    {
        for (int idx = width_ * height_; idx >= 0; --idx)
        {
            const noRoadNode* node = dynamic_cast<const noRoadNode*>(nodes[idx].obj);

            if (node)
            {
                node->last_visit = 0;
            }
        }

        current_visit_on_roads = 1;
    }

    // Anfangsknoten einfügen
    todo.clear();

    start->targetDistance = start->estimate = CalcDistance(start->GetPos(),  goal->GetPos());
    start->last_visit = current_visit_on_roads;
    start->prev = NULL;
    start->cost = start->dir_ = 0;

    todo.push(start);

    while (!todo.empty())
    {
        // Knoten mit den geringsten Wegkosten auswählen
        const noRoadNode* best = todo.top();

        // Knoten behandelt --> raus aus der todo Liste
        todo.pop();

        // Ziel erreicht,  allerdings keine Nullwege erlauben?
        if (best == goal && best->cost)
        {
            // Jeweils die einzelnen Angaben zurückgeben,  falls gewünscht (Pointer übergeben)
            if (length)
            {
                *length = best->cost;
            }

            const noRoadNode* last = best;

            while (best != start)
            {
                last = best;
                best = best->prev;
            }

            if (first_dir)
            {
                *first_dir = (unsigned char) last->dir_;
            }

            if (next_harbor)
            {
                next_harbor->x = last->GetX();
                next_harbor->y = last->GetY();
            }

            // Fertig,  es wurde ein Pfad gefunden
            if (record)
            {
                GAMECLIENT.AddPathfindingResult((unsigned char) last->dir_,  length,  next_harbor);
            }

            return true;
        }

        // Nachbarflagge bzw. Wege in allen 6 Richtungen verfolgen
        for (unsigned i = 0; i < 6; ++i)
        {
            // Gibt es auch einen solchen Weg bzw. Nachbarflagge?
            noRoadNode* neighbour = best->GetNeighbour(i);

            // Wenn nicht,  brauchen wir mit dieser Richtung gar nicht weiter zu machen
            if (!neighbour)
                continue;

            // this eliminates 1/6 of all nodes and avoids cost calculation and further checks, 
            // therefore - and because the profiler says so - it is more efficient that way
            if (neighbour == best->prev)
                continue;

            // evtl verboten?
            if (best->routes[i] == forbidden)
                continue;

            // Keine Umwege über Gebäude,  ausgenommen Häfen und Ziele
            if ((i == 1) && (neighbour != goal) && (neighbour->GetGOT() != GOT_FLAG) && (neighbour->GetGOT() != GOT_NOB_HARBORBUILDING))
            {
                continue;
            }

            // Neuer Weg für diesen neuen Knoten berechnen
            unsigned cost = best->cost + best->routes[i]->GetLength();

            // Im Warenmodus müssen wir Strafpunkte für überlastete Träger hinzuaddieren, 
            // damit der Algorithmus auch Ausweichrouten auswählt
            if (ware_mode)
            {
                cost += best->GetPunishmentPoints(i);
            }
            else if (best->routes[i]->GetRoadType() == RoadSegment::RT_BOAT)    // evtl Wasserstraße?
            {
                continue;
            }

            if (cost > max)
                continue;

            // Knoten schon auf dem Feld gebildet?
            if (neighbour->last_visit == current_visit_on_roads)
            {
                // Dann nur ggf. Weg und Vorgänger korrigieren,  falls der Weg kürzer ist
                if (cost < neighbour->cost)
                {
                    neighbour->cost = cost;
                    neighbour->prev = best;
                    neighbour->estimate = neighbour->targetDistance + cost;
                    todo.rearrange(neighbour);
                    neighbour->dir_ = i;
                }

                continue;
            }

            // Alles in Ordnung,  Knoten kann gebildet werden
            neighbour->last_visit = current_visit_on_roads;
            neighbour->cost = cost;
            neighbour->dir_ = i;
            neighbour->prev = best;

            neighbour->targetDistance = CalcDistance(neighbour->GetPos(),  goal->GetPos());
            neighbour->estimate = neighbour->targetDistance + cost;

            todo.push(neighbour);
        }

        // Stehen wir hier auf einem Hafenplatz
        if (best->GetGOT() == GOT_NOB_HARBORBUILDING)
        {
            std::vector<nobHarborBuilding::ShipConnection> scs = static_cast<const nobHarborBuilding*>(best)->GetShipConnections();

            for (unsigned i = 0; i < scs.size(); ++i)
            {
                // Neuer Weg für diesen neuen Knoten berechnen
                unsigned cost = best->cost + scs[i].way_costs;

                if (cost > max)
                    continue;

                // Knoten schon auf dem Feld gebildet?
                noRoadNode& dest = *scs[i].dest;
                if (dest.last_visit == current_visit_on_roads)
                {
                    // Dann nur ggf. Weg und Vorgänger korrigieren,  falls der Weg kürzer ist
                    if (cost < dest.cost)
                    {
                        dest.dir_ = 100;
                        dest.cost = cost;
                        dest.prev = best;
                        dest.estimate = dest.targetDistance + cost;
                        todo.rearrange(&dest);
                    }

                    continue;
                }

                // Alles in Ordnung,  Knoten kann gebildet werden
                dest.last_visit = current_visit_on_roads;

                dest.dir_ = 100;
                dest.prev = best;
                dest.cost = cost;

                dest.targetDistance = CalcDistance(dest.GetPos(),  goal->GetPos());
                dest.estimate = dest.targetDistance + cost;

                todo.push(&dest);
            }
        }
    }

    // Liste leer und kein Ziel erreicht --> kein Weg
    if(record)
        GAMECLIENT.AddPathfindingResult(0xff,  length,  next_harbor);
    return false;
}
示例#23
0
fixed
OLCTriangle::CalcScore() const
{
  // one point per km
  return ApplyHandicap(CalcDistance()*fixed(0.001));
}
double CRssiToDistanceBasicAlgorithm::CalcDistance(int RSSI) const
{
	return CalcDistance(RSSI, m_A, m_N);
}
示例#25
0
int ProcessFrame(cv::Mat *frame, cv::Mat *fg_mask, double tick) {

    double dT = ((tick - prev_tick ) / cv::getTickFrequency()); //seconds
    prev_tick = tick;
    if(with_fps) {
        printf("FPS ticks : %f\n", (float) 1 / dT);
    }
    cv::Mat hsv;
    cvtColor(*frame, hsv, CV_BGR2HSV);

    cv::erode(*fg_mask, *fg_mask, cv::Mat(), cv::Point(-1, -1), 5);
    cv::dilate(*fg_mask, *fg_mask, cv::Mat(), cv::Point(-1, -1), 8);

    if(with_gui) {
        cv::imshow("Threshold", *fg_mask);
    }
    vector<vector<cv::Point>> contours;
    cv::findContours(*fg_mask, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);

    vector<contour_t> found_contures;
    contour_t new_contour;
    int counter = 0;

    for (size_t i = 0; i < contours.size(); i++) {
        cv::Rect bBox;
        cv::Moments mu;
        bBox = cv::boundingRect(contours[i]);
        mu = moments( contours[i], false);

        if (bBox.area() >= min_area) {
            new_contour.id = counter;
            new_contour.contours = contours[i];
            new_contour.mu = mu;
            new_contour.contour_use = false;
            counter++;
            found_contures.push_back(new_contour);
        }
    }

    loadValidCounureToObject(found_contures, tracked_objects);                             //načítanie všetkých vzdialeností od kontur a usporiadanie

    std::sort(tracked_objects.begin(),tracked_objects.end(),comp);
    for (size_t i = 0; i < tracked_objects.size(); i++) {
        tracked_objects[i].set_index_object((int) i);
        if (tracked_objects[i].selected_counture.size() >= 1){                           //ak má objekt v okolí nejaké kontúry
            found_contures[tracked_objects[i].selected_counture[0].ID].candidate_object.push_back(tracked_objects[i]);    //pushne do contúry svoje ID
        }
    }
    for (size_t i = 0; i < tracked_objects.size(); i++) {


        int contourID = parsingContours(found_contures, tracked_objects[i]);

        if (contourID == -1){
            if (tracked_objects[i].counter() < 2) {
                tracked_objects.erase(tracked_objects.begin() + i);
                i--;
                continue;
            }
            else {
                if (!(tracked_objects[i].last_y_pos() > frame_height - frame_height / 6 ||
                        tracked_objects[i].last_y_pos() < frame_height / 6)) {
                    tracked_objects[i].kalmanMakeCalculate(*frame, dT);
                }
                else {
                    if (((tracked_objects[i].starting_y_pos() < frame_height / 2 &&
                            tracked_objects[i].last_y_pos() <  frame_height / 6 ) ||
                            (tracked_objects[i].starting_y_pos() > frame_height / 2 &&
                                    tracked_objects[i].last_y_pos() > frame_height - frame_height / 6)) &&
                            !(tracked_objects[i].change_startin_pos())) {

                        tracked_objects[i].kalmanMakeCalculate(*frame, dT);
                    }
                    else {
                        counterAbsPersonFlow((int) i);
                        tracked_objects.erase(tracked_objects.begin() + i);
                        i--;
                        continue;
                    }

                }
            }
            if (tracked_objects[i].get_usingRate() > 30) {
                counterAbsPersonFlow((int) i);
                tracked_objects.erase(tracked_objects.begin() + i);
                i--;
                continue;
            }
        }
        else{
            found_contures[contourID].contour_use = true;
            cv::MatND hist;// = CalcHistogramBase(hsv, found_contures[contourID].contours, contourID, tracked_objects[i].hist());
            tracked_objects[i].kalmanMakeCalculate(*frame, found_contures[contourID].mu, dT, hist);
            if (tracked_objects[i].starting_y_pos() < frame_height / 2 && tracked_objects[i].last_y_pos() > frame_height - frame_height / 4 ){
                if (counterAbsPersonFlow((int) i) == 0) {
                    tracked_objects[i].set_startingYpos(frame_height);
                    tracked_objects[i].set_change_startin_pos(true);
                }
            }
            if (tracked_objects[i].starting_y_pos() > frame_height / 2 && tracked_objects[i].last_y_pos() < frame_height / 4 ){
                if(counterAbsPersonFlow((int) i) == 0) {
                    tracked_objects[i].set_startingYpos(0);
                    tracked_objects[i].set_change_startin_pos(true);
                }
            }
        }
    }

    for (size_t i = 0; i < found_contures.size(); i++) {
        if (!found_contures[i].contour_use) {

            bool create = true;
            double x = found_contures[i].mu.m10 / found_contures[i].mu.m00;
            double y = found_contures[i].mu.m01 / found_contures[i].mu.m00;


            for (size_t k = 0; k < tracked_objects.size(); k++) {
                double distance = CalcDistance(x, tracked_objects[k].last_x_pos(), y, tracked_objects[k].last_y_pos());
                if (min_dist_to_create > distance) {
                    create = false;
                }
            }
            if (create) {
                kalmanCont newObject;
                newObject.set_id(id);
                newObject.set_startingYpos(y);
                newObject.set_startingXpos(x);

                cv::MatND hist;// = CalcHistogramContour(hsv, found_contures[i].contours, (int) i);
                newObject.kalmanMakeCalculate(*frame, found_contures[i].mu, dT, hist);

                tracked_objects.push_back(newObject);
                id++;
                id = (id > 10) ? 0 : id;
            }
        }
        found_contures[i].contour_use = false;
    }
    for (size_t i = 0; i < tracked_objects.size(); i++) {

        tracked_objects[i].add_usingRate();
        tracked_objects[i].set_counter();
        tracked_objects[i].clear_history_frams();
        if (with_gui) {
            cv::Point center;
            center.x = (int) tracked_objects[i].last_x_pos();
            center.y = (int) tracked_objects[i].last_y_pos();
            cv::circle(*frame, center, 2, CV_RGB(tracked_objects[i].R, tracked_objects[i].G, tracked_objects[i].B), -1);
            stringstream sstr;
            sstr << "Objekt" << tracked_objects[i].id();
            cv::putText(*frame, sstr.str(), cv::Point(center.x + 3, center.y - 3), cv::FONT_HERSHEY_SIMPLEX, 0.5,
                            CV_RGB(tracked_objects[i].R, tracked_objects[i].G, tracked_objects[i].B), 2);
        }
    }
    if (with_gui) {
        stringstream ss;
        ss << out;
        string counter1 = ss.str();
        putText(*frame, counter1.c_str(), cv::Point(5, 30), FONT_HERSHEY_SCRIPT_SIMPLEX, 1, cv::Scalar(0, 255, 0),1);

        stringstream ss2;
        ss2 << in;
        string counter2 = ss2.str();
        putText(*frame, counter2.c_str(), cv::Point(5, frame_height - 30), FONT_HERSHEY_SCRIPT_SIMPLEX, 1, cv::Scalar(0, 0, 255),1);
        cv::imshow("Tracking", *frame);
    }
    if (!with_gui){
       // printf("in: %d, out: %d\n",in,out);
    }
    return 0;

}
示例#26
0
  */
// 이놈은 trymoveto 제대로 되면 없어질 놈이다.
DWORD	WhereDidSphereMeetLine( VECTOR3* OUT pCandidate1, float* OUT pT1, VECTOR3* OUT pCandidate2, float* OUT pT2, VECTOR3* IN pLFrom, VECTOR3* IN pLTo, VECTOR3* IN pSPivot, float fSRadius)
{
	// 일단 라인이 아닌 점, 같은 점이 두개 들어왔는가.?
	if( IsVECTOR3Same( pLFrom, pLTo))
	{
		// 그냥 안만난걸로 하고 리턴.
		return 0;
	}

	// 근의 공식 -_-;   (-b (+-) 루트(b*b-4ac) )/(2a)
	VECTOR3		V;
	float		tV;
	FindNearestVertexOnLine( &V, &tV, pLFrom, pLTo, pSPivot);
	float		fPV	=	CalcDistance( &V, pSPivot);

	if( (fPV - fSRadius) >= 0.5 )			//	아무것도 만나지 않는다.
	{
		return	0;		// 만난 점 없다 리턴.
	}

	// 하나, 또는 두개의 점에서 만난다. 판별은 b제곱-4ac로.
	float	t1;		// 첫번째 점.
	float	t2;		// 두번째 점.
	float	a, b, c;


	a	=	((*pLTo).x-(*pLFrom).x)*((*pLTo).x-(*pLFrom).x)	+	((*pLTo).y-(*pLFrom).y)*((*pLTo).y-(*pLFrom).y)	+	((*pLTo).z-(*pLFrom).z)*((*pLTo).z-(*pLFrom).z);
	b	=	2*( ((*pLTo).x-(*pLFrom).x)*((*pLFrom).x-(*pSPivot).x) + ((*pLTo).y-(*pLFrom).y)*((*pLFrom).y-(*pSPivot).y) + ((*pLTo).z-(*pLFrom).z)*((*pLFrom).z-(*pSPivot).z) );
	c	=	((*pLFrom).x-(*pSPivot).x)*((*pLFrom).x-(*pSPivot).x)	+	((*pLFrom).y-(*pSPivot).y)*((*pLFrom).y-(*pSPivot).y)	+	((*pLFrom).z-(*pSPivot).z)*((*pLFrom).z-(*pSPivot).z) - fSRadius*fSRadius;
示例#27
0
/// Wegfinden ( A* ),  O(v lg v) --> Wegfindung auf allgemeinen Terrain (ohne Straßen),  für Wegbau und frei herumlaufende Berufe
bool GameWorldBase::FindFreePathAlternatingConditions(const MapPoint start, 
                                 const MapPoint dest,  const bool random_route, 
                                 const unsigned max_route,  std::vector<unsigned char>* route,  unsigned* length, 
                                 unsigned char* first_dir,   FP_Node_OK_Callback IsNodeOK,  FP_Node_OK_Callback IsNodeOKAlternate,  FP_Node_OK_Callback IsNodeToDestOk,  const void* param,  const bool record) const
{
    // increase currentVisit,  so we don't have to clear the visited-states at every run
    currentVisit++;
	//currentVisitEven++;

    // if the counter reaches its maxium,  tidy up
    if (currentVisit == std::numeric_limits<unsigned>::max() - 1)
    {
        for (unsigned i = 0; i < (maxMapSize * maxMapSize); ++i)
        {
            pf_nodes[i].lastVisited = 0;
			pf_nodes[i].lastVisitedEven = 0;
        }
        currentVisit = 1;
		//currentVisitEven = 1;
    }

    std::list<PathfindingPoint> todo;
	bool prevstepEven=true; //flips between even and odd 
	unsigned stepsTilSwitch=1;
    PathfindingPoint::Init(dest,  this);

    // Anfangsknoten einfügen
    unsigned start_id = MakeCoordID(start);
	todo.push_back(PathfindingPoint(start,  start_id));
    // Und mit entsprechenden Werten füllen
    //pf_nodes[start_id].it_p = ret.first;
    pf_nodes[start_id].prevEven = INVALID_PREV;
    pf_nodes[start_id].lastVisitedEven = currentVisit;
    pf_nodes[start_id].wayEven = 0;
    pf_nodes[start_id].dirEven = 0;
	//LOG.lprintf("pf: from %i, %i to %i, %i \n", x_start, y_start, x_dest, y_dest);
    // TODO confirm random
    unsigned rand = GetIdx(start) * GAMECLIENT.GetGFNumber() % 6; //RANDOM.Rand(__FILE__,  __LINE__,  y_start * GetWidth() + x_start,  6);

	while(!todo.empty())
    {		
		if(!stepsTilSwitch) //counter for next step and switch condition
		{			
			prevstepEven=!prevstepEven;
			stepsTilSwitch=todo.size();
			//prevstepEven? LOG.lprintf("pf: even,  to switch %i listsize %i ", stepsTilSwitch, todo.size()) : LOG.lprintf("pf: odd,  to switch %i listsize %i ", stepsTilSwitch, todo.size());
		}
		//else
			//prevstepEven? LOG.lprintf("pf: even,  to switch %i listsize %i ", stepsTilSwitch, todo.size()) : LOG.lprintf("pf: odd,  to switch %i listsize %i ", stepsTilSwitch, todo.size());
		stepsTilSwitch--;

        // Knoten mit den geringsten Wegkosten auswählen
        PathfindingPoint best = *todo.begin();
        // Knoten behandelt --> raus aus der todo Liste
        todo.erase(todo.begin());

        //printf("x: %u y: %u\n", best.x, best.y);

        // ID des besten Punktes ausrechnen

        unsigned best_id = best.id;
		//LOG.lprintf(" now %i, %i id: %i \n", best.x, best.y, best_id);
        // Dieser Knoten wurde aus dem set entfernt,  daher wird der entsprechende Iterator
        // auf das Ende (also nicht definiert) gesetzt,  quasi als "NULL"-Ersatz
        //pf_nodes[best_id].it_p = todo.end();

        // Ziel schon erreicht? Allerdings Null-Weg,  wenn Start=Ende ist,  verbieten
        if(dest == best.pt && ((prevstepEven && pf_nodes[best_id].wayEven) || (!prevstepEven && pf_nodes[best_id].way)))
        {
            // Ziel erreicht!
            // Jeweils die einzelnen Angaben zurückgeben,  falls gewünscht (Pointer übergeben)
            if(length)
				*length = prevstepEven ? pf_nodes[best_id].wayEven : pf_nodes[best_id].way;
            if(route)
                prevstepEven? route->resize(pf_nodes[best_id].wayEven) : route->resize(pf_nodes[best_id].way);

            // Route rekonstruieren und ggf. die erste Richtung speichern,  falls gewünscht
			bool alternate=prevstepEven;
            for(unsigned z = prevstepEven? pf_nodes[best_id].wayEven - 1 : pf_nodes[best_id].way - 1; best_id != start_id; --z,  best_id = alternate? pf_nodes[best_id].prevEven : pf_nodes[best_id].prev,  alternate=!alternate)
            {
                if(route)
                    (*route)[z] = alternate? pf_nodes[best_id].dirEven : pf_nodes[best_id].dir;
                if(first_dir && z == 0)
                    *first_dir = pf_nodes[best_id].dirEven;				
            }

            // Fertig,  es wurde ein Pfad gefunden
            return true;
        }

        // Maximaler Weg schon erreicht? In dem Fall brauchen wir keine weiteren Knoten von diesem aus bilden
        if((prevstepEven && pf_nodes[best_id].wayEven)==max_route || (!prevstepEven && pf_nodes[best_id].way == max_route))
            continue;

        // Bei Zufälliger Richtung anfangen (damit man nicht immer denselben Weg geht,  besonders für die Soldaten wichtig)
        unsigned startDir = random_route ? rand : 0;
		//LOG.lprintf("pf get neighbor nodes %i, %i id: %i \n", best.x, best.y, best_id);
        // Knoten in alle 6 Richtungen bilden
        for(unsigned z = startDir + 3; z < startDir + 9; ++z)
        {
            unsigned i = z % 6;

            // Koordinaten des entsprechenden umliegenden Punktes bilden
            MapPoint na = GetNeighbour(best.pt,  i);

            // ID des umliegenden Knotens bilden
            unsigned xaid = MakeCoordID(na);

            // Knoten schon auf dem Feld gebildet?
            if ((prevstepEven && pf_nodes[xaid].lastVisited == currentVisit) || (!prevstepEven && pf_nodes[xaid].lastVisitedEven == currentVisit))
            {
                continue;
            }

            // Das Ziel wollen wir auf jedenfall erreichen lassen,  daher nur diese zusätzlichen
            // Bedingungen,  wenn es nicht das Ziel ist
            if(na != dest && ((prevstepEven && IsNodeOK) || (!prevstepEven && IsNodeOKAlternate)))
            {
                if(prevstepEven)
				{
					if(!IsNodeOK(*this,  na,  i,  param))
						continue;
				}
				else
				{
					if (!IsNodeOKAlternate(*this,  na,  i,  param))
						continue;
					MapPoint p = best.pt;

					std::vector<MapPoint>evenlocationsonroute;
					bool alternate=prevstepEven;
					unsigned back_id=best_id;
					for(unsigned i=pf_nodes[best_id].way-1; i>1; i--, back_id = alternate? pf_nodes[back_id].prevEven : pf_nodes[back_id].prev,  alternate=!alternate) // backtrack the plannend route and check if another "even" position is too close
					{
						unsigned char pdir = alternate? pf_nodes[back_id].dirEven : pf_nodes[back_id].dir;
						p = GetNeighbour(p,  (pdir+3)%6);
						if(i%2==0) //even step
						{	
							evenlocationsonroute.push_back(p);
						}
					}
					bool tooclose=false;
					//LOG.lprintf("pf from %i, %i to %i, %i now %i, %i ", x_start, y_start, x_dest, y_dest, xa, ya);//\n
					for(std::vector<MapPoint>::const_iterator it=evenlocationsonroute.begin();it!=evenlocationsonroute.end(); ++it)
					{
						//LOG.lprintf("dist to %i, %i ", temp, *it);
						if(CalcDistance(na,  (*it))<2)
						{
							tooclose=true;
							break;
						}
					}
					//LOG.lprintf("\n");
					if(CalcDistance(na,  start)<2)
						continue;
					if(CalcDistance(na,  dest)<2)
						continue;
					if(tooclose)
						continue;
				}
            }

            // Zusätzliche Bedingungen,  auch die das letzte Stück zum Ziel betreffen
            if(IsNodeToDestOk)
            {
                if(!IsNodeToDestOk(*this,  na,  i,  param))
                    continue;
            }

            // Alles in Ordnung,  Knoten kann gebildet werden
            prevstepEven? pf_nodes[xaid].lastVisited = currentVisit			: pf_nodes[xaid].lastVisitedEven = currentVisit;
            prevstepEven? pf_nodes[xaid].way = pf_nodes[best_id].wayEven + 1: pf_nodes[xaid].wayEven = pf_nodes[best_id].way + 1;
            prevstepEven? pf_nodes[xaid].dir = i							: pf_nodes[xaid].dirEven = i;
            prevstepEven? pf_nodes[xaid].prev = best_id						: pf_nodes[xaid].prevEven = best_id	;

            todo.push_back(PathfindingPoint(na,  xaid));
            //pf_nodes[xaid].it_p = ret.first;
        }
    }

    // Liste leer und kein Ziel erreicht --> kein Weg
    return false;
}