Layered Isotile Map Mauskoord

Design Patterns, Erklärungen zu Algorithmen, Optimierung, Softwarearchitektur
Forumsregeln
Wenn das Problem mit einer Programmiersprache direkt zusammenhängt, bitte HIER posten.
Antworten
marfi
Beiträge: 10
Registriert: 16.12.2002, 13:39
Kontaktdaten:

Layered Isotile Map Mauskoord

Beitrag von marfi »

Hallo Leute!

Seit einigen Tagen verzweifel ich an einem kleinen Stückchen Code. Und zwar erstelle ich ein Flatterrand Isotile Gitter und möchte einen beliebiegen Positionsvector in ein Tile (Raute) zurückrechnen.

Erstemal der Code zum erstellen des Gitters.

Code: Alles auswählen

	//////////////////////////////////////////////////////////////////////////
	// create the waypoints
	//////////////////////////////////////////////////////////////////////////
	for(int y = 0; y < m_pvecWaypointCount->_Y; y++)
	{
		for(int x = 0; x < m_pvecWaypointCount->_X; x++)
		{
			if(y%2==0)
				X1 = W2 + m_pvecSizeOfTiles->_X * x;
			else
				X1 = m_pvecSizeOfTiles->_X * x;

			Y1 = y * H2 + m_pvecSizeOfTiles->_Y;
		
			if(nIndex<=m_nWaypointCount)
			{
			
				// create new node
				m_pWaypointList[nIndex]._vecPosition = CVector2D(X1,Y1);
				m_pWaypointList[nIndex]._pParent	 = NULL;
				m_pWaypointList[nIndex]._bClosedList = false;
				m_pWaypointList[nIndex]._bOpenList	 = false;
				m_pWaypointList[nIndex]._bWalkable	 = true;
				

							}
			

		}
	}
Wenn ich jetzt passende Koordinaten zurückrechnen möchte kann ich das ja ganz einfach durch umstellen der Formel und auflösen nach X.
bzw Y.
Funktioniert auch super. Wenn aber der Positionsvector nicht genau passend ist und nach division ein Rest bleibt, habe ich einfach den minimalen und maximalen index berechnet und suche dann die kürzeste Entfernung zwischen den Indizies. Auf der X-Achse funktioniert das, Auf der Y-Achse nur wenn Position.y größer als Waypoint.y. Ansosten wird ein Tile rechts oder links oberhalb daneben ausgewählt.

Code: Alles auswählen

SWaypoint* CGraphPathfinder::GetWaypoint(int& nIndexOut, CVector2D vecPosition)
{
	int nIndexX, nIndexY, nIndex, XMin, XMax, YMin, YMax, nIndexMin, nIndexMax, nNearestWaypoint;
	int  nIndexX0, nIndexY0,nIndexX1, nIndexX2, nIndexY1, nIndexY2;

	


	/*
	if(int(vecPosition._Y / (m_pvecSizeOfTiles->_Y/2))%2!=0) // wenn y pos gerade, dann y aufrunden und x abrunden
	{
		nIndexY = static_cast<int>((vecPosition._Y - m_pvecSizeOfTiles->_Y)/(m_pvecSizeOfTiles->_Y/2)+.5);
	}
	else
	{
		nIndexY = (vecPosition._Y - m_pvecSizeOfTiles->_Y)/(m_pvecSizeOfTiles->_Y/2);
	}*/
	
	// Wenn x oder y Position nicht durch die Breite bzw Höhe teilbar, dann suche den Punkt,
	// der x und y am nächsten kommt
	if((int(vecPosition._X)%int(m_pvecSizeOfTiles->_X) !=0) || (int(vecPosition._Y-m_pvecSizeOfTiles->_Y)%int(m_pvecSizeOfTiles->_Y/2) !=0))
	{

		// Zum Test die min max X-Werte anders berechen 16.11.2011
		XMin = static_cast<int>((vecPosition._X / m_pvecSizeOfTiles->_X)); // abrunden
		XMax = static_cast<int>(((vecPosition._X + (m_pvecSizeOfTiles->_X/2)) / m_pvecSizeOfTiles->_X)+.5); // aufrunden

		YMin = (vecPosition._Y - m_pvecSizeOfTiles->_Y)/(m_pvecSizeOfTiles->_Y/2);
		YMax = static_cast<int>((vecPosition._Y - m_pvecSizeOfTiles->_Y)/(m_pvecSizeOfTiles->_Y/2)+.5);
                                // Zum Test zusätzlich die Reihe oberhalb einbeziehen 
		nIndexX0 = (YMin-1 * m_pvecWaypointCount->_X) + XMin;
		nIndexY0 = (YMin-1 * m_pvecWaypointCount->_X) + XMax;

		nIndexX1 = (YMin * m_pvecWaypointCount->_X) + XMin;
		nIndexX2 = (YMin * m_pvecWaypointCount->_X) + XMax;

		nIndexY1 = (YMax * m_pvecWaypointCount->_X) + XMin;
		nIndexY2 = (YMax * m_pvecWaypointCount->_X) + XMax;

		nIndex = GetNearest(vecPosition, nIndexX0,nIndexY0);

		nIndexX = GetNearest(vecPosition, nIndexX1,nIndexX2);

		nIndexY = GetNearest(vecPosition, nIndexY1,nIndexY2);
		//////////////////////////////////////////////////////////////////////////

		nIndexMin = GetNearest(vecPosition, nIndex,nIndexX);

		nNearestWaypoint = GetNearest(vecPosition, nIndexMin,nIndexY);

		//nNearestWaypoint = GetNearest(vecPosition, nIndexX,nIndexY);

	

		
		nIndexOut = nNearestWaypoint;
		// return the waypoint that was found
		return &m_pWaypointList[nNearestWaypoint];
	}
	else // Koordinaten passen zu einem Waypoint
	{
		//////////////////////////////////////////////////////////////////
		// Funktioniert nur wenn genau die Koordinaten des Wegpunktes getroffen werden
		//////////////////////////////////////////////////////////////////
		
		// zuerst den Y index ausrechnen
		nIndexY = (vecPosition._Y - m_pvecSizeOfTiles->_Y)/(m_pvecSizeOfTiles->_Y/2);
		// wenn y gerade
		if(nIndexY %2==0)
			nIndexX = (vecPosition._X - (m_pvecSizeOfTiles->_X/2))/m_pvecSizeOfTiles->_X;
		else // wenn y ungerade
			nIndexX = vecPosition._X / m_pvecSizeOfTiles->_X;
		
		// Gesamtindex berechnen
		nIndex = (nIndexY * m_pvecWaypointCount->_X) + nIndexX;
		
		// prüfe Gültigkeit
		if((nIndex > 0 ) && (nIndex < m_nWaypointCount))
			return &m_pWaypointList[nIndex];
	}
	
	return NULL;

	



}
Irgendwie stehe ich gerade auf dem Schlauch. Ich möchte nicht extra die vier gefundenen Indizies mit PointInPolygon() prüfen. Man muss das noch auch einfach so zurückrechnen können. Oder nicht?
Also wie gesagt mein Lösungsansatz funktioniert fast :)

Habe ich etwas übersehen?
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4258
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: Layered Isotile Map Mauskoord

Beitrag von Chromanoid »

Mal das hier angeschaut: http://zfx.info/viewtopic.php?f=7&t=1967 ?
marfi
Beiträge: 10
Registriert: 16.12.2002, 13:39
Kontaktdaten:

Re: Layered Isotile Map Mauskoord

Beitrag von marfi »

Ja, das habe ich mir schon angesehen. Aber es geht dort nicht um Flatterrand Isomap. Aber ich lese es mir nochmal durch, vielleicht finde ich ja was brauchbares.

Ansonsten test ich einfach als pointInPolygon,
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4258
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: Layered Isotile Map Mauskoord

Beitrag von Chromanoid »

Verstehe. Falls du das noch nicht so vorhast müsste auch der Abstand zum Quadrat zu zwei aneinander liegenden Seiten reichen.
marfi
Beiträge: 10
Registriert: 16.12.2002, 13:39
Kontaktdaten:

Re: Layered Isotile Map Mauskoord

Beitrag von marfi »

Danke!
Hab den Fehler gefunden!! :)

Ich dachte immer 4 Indizies zu haben. Dem war aber nicht so. Es wurde nicht immer aufgerundet. Blöd ^^

Ist mir erst aufgefallen als ich PointInPolygon implemeniert habe. Ich habe mir alle Indizies als polygon anzeigen lassen
um zu sehen ob meine PiP Funktion funktioniert. Da habe ich bemerkt,dass im kritischen Bereich nur zwei Indizies aktiv waren.


So ist es richtig!

Code: Alles auswählen


		XMin = static_cast<int>((vecPosition._X / m_pvecSizeOfTiles->_X)); // abrunden
		XMax = XMin+1;

		YMin = (vecPosition._Y - m_pvecSizeOfTiles->_Y)/(m_pvecSizeOfTiles->_Y/2);
		YMax = YMin+1;
Antworten