Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

Triangulating complex polygons

Name: Anonymous 2009-03-17 20:02

I'm trying to find an easy to implement algorithm that will take a non-convex polygon with no holes and find a triangulation of it.  My googling is returning a lot of math when what I really need is an algorithm or some source code to work from.

Name: Anonymous 2009-03-18 7:02

    originalVerts = ds->numVerts;
   
    numVerts = 0;
    for ( i = 0 ; i < ds->numVerts ; i++ )
    {
        counts[i] = 0;
        firstVert[i] = numVerts;

        // copy first vert
        if ( numVerts == MAX_SURFACE_VERTS ) {
            Error( "MAX_SURFACE_VERTS" );
        }
        verts[numVerts] = ds->verts[i];
        originals[numVerts] = i;
        numVerts++;

        // check to see if there are any t junctions before the next vert
        v1 = &ds->verts[i];
        v2 = &ds->verts[ (i+1) % ds->numVerts ];

        j = (int)ds->verts[i].lightmap[ 0 ][ 0 ];
        if ( j == -1 ) {
            continue;        // degenerate edge
        }
        e = &edgeLines[ j ];
       
        VectorSubtract( v1->xyz, e->origin, delta );
        start = DotProduct( delta, e->dir );

        VectorSubtract( v2->xyz, e->origin, delta );
        end = DotProduct( delta, e->dir );


        if ( start < end ) {
            p = e->chain.next;
        } else {
            p = e->chain.prev;
        }

        for (  ; p != &e->chain ;  ) {
            if ( start < end ) {
                if ( p->intercept > end - ON_EPSILON ) {
                    break;
                }
            } else {
                if ( p->intercept < end + ON_EPSILON ) {
                    break;
                }
            }

            if (
                ( start < end && p->intercept > start + ON_EPSILON ) ||
                ( start > end && p->intercept < start - ON_EPSILON ) ) {
                // insert this point
                if ( numVerts == MAX_SURFACE_VERTS ) {
                    Error( "MAX_SURFACE_VERTS" );
                }
               
                /* take the exact intercept point */
                VectorCopy( p->xyz, verts[ numVerts ].xyz );
               
                /* interpolate the texture coordinates */
                frac = ( p->intercept - start ) / ( end - start );
                for ( j = 0 ; j < 2 ; j++ ) {
                    verts[ numVerts ].st[j] = v1->st[j] +
                        frac * ( v2->st[j] - v1->st[j] );
                }
               
                /* copy the normal (FIXME: what about nonplanar surfaces? */
                VectorCopy( v1->normal, verts[ numVerts ].normal );
               
                /* ydnar: interpolate the color */
                for( k = 0; k < MAX_LIGHTMAPS; k++ )
                {
                    for( j = 0; j < 4; j++ )
                    {
                        c = (float) v1->color[ k ][ j ] + frac * ((float) v2->color[ k ][ j ] - (float) v1->color[ k ][ j ]);
                        verts[ numVerts ].color[ k ][ j ] = (byte) (c < 255.0f ? c : 255);
                    }
                }
               
                /* next... */
                originals[ numVerts ] = i;
                numVerts++;
                counts[ i ]++;
            }

            if ( start < end ) {
                p = p->next;
            } else {
                p = p->prev;
            }
        }
    }

    c_addedVerts += numVerts - ds->numVerts;
    c_totalVerts += numVerts;


    // FIXME: check to see if the entire surface degenerated
    // after snapping

    // rotate the points so that the initial vertex is between
    // two non-subdivided edges
    for ( i = 0 ; i < numVerts ; i++ ) {
        if ( originals[ (i+1) % numVerts ] == originals[ i ] ) {
            continue;
        }
        j = (i + numVerts - 1 ) % numVerts;
        k = (i + numVerts - 2 ) % numVerts;
        if ( originals[ j ] == originals[ k ] ) {
            continue;
        }
        break;
    }

    if ( i == 0 ) {
        // fine the way it is
        c_natural++;

        ds->numVerts = numVerts;
        ds->verts = safe_malloc( numVerts * sizeof( *ds->verts ) );
        memcpy( ds->verts, verts, numVerts * sizeof( *ds->verts ) );

        return;
    }
    if ( i == numVerts ) {
        // create a vertex in the middle to start the fan
        c_cant++;

/*
        memset ( &verts[numVerts], 0, sizeof( verts[numVerts] ) );
        for ( i = 0 ; i < numVerts ; i++ ) {
            for ( j = 0 ; j < 10 ; j++ ) {
                verts[numVerts].xyz[j] += verts[i].xyz[j];
            }
        }
        for ( j = 0 ; j < 10 ; j++ ) {
            verts[numVerts].xyz[j] /= numVerts;
        }

        i = numVerts;
        numVerts++;
*/
    } else {
        // just rotate the vertexes
        c_rotate++;

    }

    ds->numVerts = numVerts;
    ds->verts = safe_malloc( numVerts * sizeof( *ds->verts ) );

    for ( j = 0 ; j < ds->numVerts ; j++ ) {
        ds->verts[j] = verts[ ( j + i ) % ds->numVerts ];
    }


Hope that helps!

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List