Poslao: 10 Apr 2013 18:24
|
offline
- morando
- Građanin
- Pridružio: 19 Maj 2011
- Poruke: 297
|
Recimo da imam tacke koje opisuju jedan konveksan poligon, treba da generisem indexe tacaka trouglova koje ispadaju od tog poligona da bih posle mogao da ih iscrtam.
Nesto sam ja probao ali vizuelno kad pogledam dobijam pogresan rezlutat, mislim da negde gresim:
std::vector<WORD> vTriIndices;
std::vector<D3DXVECTOR3> vPoints;
...
for(...)
{
std::vector<D3DXVECTOR3> vPolygon;
...
assert( vPolygon.size() >= 3 );
vPoints.insert(vPoints.end(), vPolygon.begin(), vPolygon.end()); // append vertices
// make "triangle fan" of convex polygon
for(std::size_t k = 0; k < vPolygon.size() - 2; ++k)
{
WORD inx0 = 0;
if(!vTriIndices.empty())
{
inx0 = vPoints.size() - 1;
}
WORD inx1 = inx0 + k + 1;
WORD inx2 = inx0 + k + 2;
vTriIndices.push_back( inx0 );
vTriIndices.push_back( inx1 );
vTriIndices.push_back( inx2 );
}
}
EDIT:
Treba da se stavi append-ovanje ispod petlje zbog prvog indexa, ali opet nije to to.
...
//vPoints.insert(vPoints.end(), vPolygon.begin(), vPolygon.end()); // append vertices
// make "triangle fan" of convex polygon
for(std::size_t k = 0; k < vPolygon.size() - 2; ++k)
{
WORD inx0 = 0;
if(!vTriIndices.empty())
{
inx0 = vPoints.size() - 1;
}
WORD inx1 = inx0 + k + 1;
WORD inx2 = inx0 + k + 2;
vTriIndices.push_back( inx0 );
vTriIndices.push_back( inx1 );
vTriIndices.push_back( inx2 );
}
vPoints.insert(vPoints.end(), vPolygon.begin(), vPolygon.end()); // append vertices
}
EDIT: Jos jedna ispravka , ali jos nije u redu.
...
// make "triangle fan" of convex polygon
for(std::size_t k = 0; k < vPolygon.size() - 2; ++k)
{
WORD inx0 = 0;
// if(!vTriIndices.empty())
if(!vPoints.empty())
{
inx0 = vPoints.size() - 1;
}
...
|
|
|
Registruj se da bi učestvovao u diskusiji. Registrovanim korisnicima se NE prikazuju reklame unutar poruka.
|
|
Poslao: 10 Apr 2013 18:54
|
offline
- Srki_82
- Moderator foruma
- Srđan Tot
- Am I evil? I am man, yes I am.
- Pridružio: 12 Jul 2005
- Poruke: 2483
- Gde živiš: Ljubljana
|
Znam da nije odgovor koji si želeo, ali zašto ne koristiš triangle fan? U tom slučaju ti indeksi nisu ni potrebni.
|
|
|
|
|
Poslao: 11 Apr 2013 15:20
|
offline
- Srki_82
- Moderator foruma
- Srđan Tot
- Am I evil? I am man, yes I am.
- Pridružio: 12 Jul 2005
- Poruke: 2483
- Gde živiš: Ljubljana
|
Ako ti je samo to problem, najlakši način je da nađeš približan centar objekta i da ređaš tačke u odnosu na ugao između vertikalne linije koja prolazi kroz centar i one koja prolazi kroz centar i datu tačku na poligonu.
|
|
|
|
Poslao: 11 Apr 2013 18:28
|
offline
- morando
- Građanin
- Pridružio: 19 Maj 2011
- Poruke: 297
|
Napisano: 11 Apr 2013 16:29
Centar mogu da dobije izracunavajuci AABB od datih tacaka, AABB half-extent dodje kao radijus i onda samo:
adjacent = length( center - vertex[i] )
hypotenuse = length( center - vertex[i + n] )
cos( a ) = adjacent / hypotenuse
Jel tako?
Posle cu imati i drugi problem, ne znam kako da ga sortiram da dodje CCW ( counterclockwise) da mi ne bi bilo flip-ovano.
Dopuna: 11 Apr 2013 18:28
Joooj, majko moja.
Opet negde gresim sa logikom. Probao sam da sastavim algo prema tvojoj ideji ali mi ne radi kako treba, imam i dalje "supu" od trouglova.
Vidis li negde gresku?
typedef std::vector<D3DXVECTOR3>::iterator v_pt_iter;
D3DXVECTOR3 getPtsCenter(std::vector<D3DXVECTOR3>& v)
{
D3DXVECTOR3 outCenter(0.0f, 0.0f, 0.0f);
float maxF = std::numeric_limits<float>::max();
float minF = std::numeric_limits<float>::min();
D3DXVECTOR3 minPt(maxF, maxF, maxF);
D3DXVECTOR3 maxPt(minF, minF, minF);
for(std::size_t i = 0; i < v.size(); ++i)
{
// min
if(minPt.x > v[i].x)
{
minPt.x = v[i].x;
}
if(minPt.y > v[i].y)
{
minPt.y = v[i].y;
}
if(minPt.z > v[i].z)
{
minPt.z = v[i].z;
}
// max
if(maxPt.x < v[i].x)
{
maxPt.x = v[i].x;
}
if(maxPt.y < v[i].y)
{
maxPt.y = v[i].y;
}
if(maxPt.z < v[i].z)
{
maxPt.z = v[i].z;
}
}
outCenter = (maxPt + minPt) * 0.5f;
return outCenter;
}
v_pt_iter findSmallestAngle(const D3DXVECTOR3& center, const D3DXVECTOR3& currPt, v_pt_iter begIt, v_pt_iter endIt)
{
v_pt_iter outIt = endIt;
float cosA = std::numeric_limits<float>::max();
float adjacent = D3DXVec3Length(&(center - currPt));
for(; begIt != endIt; ++begIt)
{
float hypotenuse = D3DXVec3Length(&(center - *begIt));
float currCosA = adjacent / hypotenuse;
if(cosA > currCosA)
{
cosA = currCosA;
outIt = begIt;
}
}
return outIt;
}
std::vector<D3DXVECTOR3> getSortedPtList(std::vector<D3DXVECTOR3>& v)
{
std::vector<D3DXVECTOR3> vOut(v.size());
vOut.push_back(v.front());
std::swap(v.front(), v.back());
v.pop_back();
D3DXVECTOR3 center = getPtsCenter(v);
while(!v.empty())
{
auto smCosAIt = findSmallestAngle(center, vOut.back(), v.begin(), v.end());
vOut.push_back(*smCosAIt);
std::size_t pos = std::distance(v.begin(), smCosAIt);
std::swap(v[pos], v.back());
v.pop_back();
}
return vOut;
}
|
|
|
|
|
|