Exemplo n.º 1
0
//----------------------------------------------------------------------------
void ConvexHull2D::GenerateHull2D ()
{
    // Generate random points.
    mNumVertices = 256;
    delete1(mVertices);
    mVertices = new1<Vector2f>(mNumVertices);
    for (int i = 0; i < mNumVertices; ++i)
    {
        mVertices[i].X() = Mathf::UnitRandom();
        mVertices[i].Y() = Mathf::UnitRandom();
    }

    RegenerateHull();
    assertion(mHull->GetDimension() == 2, "Incorrect dimension.\n");
}
Exemplo n.º 2
0
//----------------------------------------------------------------------------
void ConvexHull2D::GenerateHull0D ()
{
    mNumVertices = 8;
    delete1(mVertices);
    mVertices = new1<Vector2f>(mNumVertices);
    mVertices[0].X() = Mathf::UnitRandom();
    mVertices[0].Y() = Mathf::UnitRandom();
    for (int i = 1; i < mNumVertices; ++i)
    {
        float sign = (Mathf::SymmetricRandom() > 0.0f ? 1.0f : -1.0f);
        mVertices[i].X() = mVertices[0].X() + sign*0.00001f;
        mVertices[i].Y() = mVertices[0].Y() + sign*0.00001f;
    }

    RegenerateHull();
    assertion(mHull->GetDimension() == 0, "Incorrect dimension.\n");
}
Exemplo n.º 3
0
//----------------------------------------------------------------------------
void ConvexHull2D::GenerateHullManyCollinear ()
{
    // Generate a lot of nearly collinear points.
    mNumVertices = 128;
    delete1(mVertices);
    mVertices = new1<Vector2f>(mNumVertices);

    Vector2f center(0.5f, 0.5f);
    Vector2f U0(Mathf::SymmetricRandom(), Mathf::SymmetricRandom());
    U0.Normalize();
    Vector2f U1 = U0.Perp();
    float e0 = 0.5f*Mathf::UnitRandom();
    float e1 = 0.5f*Mathf::UnitRandom();

    float t;
    int i;
    for (i = 0; i < mNumVertices/4; ++i)
    {
        t = i/(mNumVertices/4.0f);
        mVertices[i] =
            center - e0*U0 - e1*U1 + 2.0f*e0*t*U0;
    }
    for (i = 0; i < mNumVertices/4; i++)
    {
        t = i/(mNumVertices/4.0f);
        mVertices[i + mNumVertices/4] =
            center + e0*U0 - e1*U1 + 2.0f*e1*t*U1;
    }
    for (i = 0; i < mNumVertices/4; i++)
    {
        t = i/(mNumVertices/4.0f);
        mVertices[i + mNumVertices/2] =
            center + e0*U0 + e1*U1 - 2.0f*e0*t*U0;
    }
    for (i = 0; i < mNumVertices/4; i++)
    {
        t = i/(mNumVertices/4.0f);
        mVertices[i + 3*mNumVertices/4] =
            center - e0*U0 + e1*U1 - 2.0f*e1*t*U1;
    }

    RegenerateHull();
    assertion(mHull->GetDimension() == 2, "Incorrect dimension.\n");
}
Exemplo n.º 4
0
//----------------------------------------------------------------------------
void ConvexHull2D::GenerateHull1D ()
{
    mNumVertices = 32;
    delete1(mVertices);
    mVertices = new1<Vector2f>(mNumVertices);
    int qm1 = mNumVertices - 1;
    mVertices[0].X() = Mathf::UnitRandom();
    mVertices[0].Y() = Mathf::UnitRandom();
    mVertices[qm1].X() = Mathf::UnitRandom();
    mVertices[qm1].Y() = Mathf::UnitRandom();
    for (int i = 1; i < qm1; ++i)
    {
        float sign = (Mathf::SymmetricRandom() > 0.0f ? 1.0f : -1.0f);
        float t = Mathf::UnitRandom();
        mVertices[i] = (1.0f - t)*mVertices[0] + t*mVertices[qm1];
        mVertices[i].X() += sign*0.00001f;
        mVertices[i].Y() += sign*0.00001f;
    }

    RegenerateHull();
    assertion(mHull->GetDimension() == 1, "Incorrect dimension.\n");
}
Exemplo n.º 5
0
//----------------------------------------------------------------------------
void ConvexHull3D::CreateHull ()
{
    int numVertices = mLimitedQuantity;

    VertexFormat* vformat = VertexFormat::Create(2,
        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
        VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT3, 0);
    int vstride = vformat->GetStride();

    VertexBuffer* vbuffer = new0 VertexBuffer(numVertices, vstride);
    VertexBufferAccessor vba(vformat, vbuffer);
    int i;
    for (i = 0; i < numVertices; ++i)
    {
        vba.Position<Vector3f>(i) = mVertices[i];
        vba.Color<Float3>(0, i) = mColors[i];
    }

    RegenerateHull();

    int numTriangles = 0;
    TriMesh* mesh = 0;

    switch (mHull->GetDimension())
    {
    case 0:
        sprintf(mFooter, "point: v = %d, t = %d", numVertices, numTriangles);
        return;
    case 1:
        sprintf(mFooter, "linear: v = %d, t = %d", numVertices, numTriangles);
        return;
    case 2:
    {
        numTriangles = mHull->GetNumSimplices() - 2;
        const int* hullIndices = mHull->GetIndices();
        IndexBuffer* ibuffer = new0 IndexBuffer(3*numTriangles, sizeof(int));
        int* indices = (int*)ibuffer->GetData();
        for (int t = 0, i0 = 1, i1 = 2; t < numTriangles; ++t, ++i0, ++i1)
        {
            *indices++ = hullIndices[0];
            *indices++ = hullIndices[i0];
            *indices++ = hullIndices[i1];
        }
        mesh = new0 TriMesh(vformat, vbuffer, ibuffer);
        mesh->SetEffectInstance(VertexColor3Effect::CreateUniqueInstance());

        sprintf(mFooter, "planar: v = %d, t = %d", numVertices, numTriangles);
        break;
    }
    case 3:
        numTriangles = mHull->GetNumSimplices();
        const int* hullIndices = mHull->GetIndices();
        IndexBuffer* ibuffer = new0 IndexBuffer(3*numTriangles, sizeof(int));
        int* indices = (int*)ibuffer->GetData();
        memcpy(indices, hullIndices, 3*numTriangles*sizeof(int));
        mesh = new0 TriMesh(vformat, vbuffer, ibuffer);
        mesh->SetEffectInstance(VertexColor3Effect::CreateUniqueInstance());

        sprintf(mFooter, "spatial: v = %d, t = %d", numVertices,
            numTriangles);
        break;
    }

    // Translate to center of mass.
    Vector3f center = mVertices[0];
    for (i = 1; i < mLimitedQuantity; ++i)
    {
        center += mVertices[i];
    }
    center /= (float)mLimitedQuantity;
    mesh->LocalTransform.SetTranslate(-center);
    mTrnNode->SetChild(0, mesh);

    for (i = 2; i < mLimitedQuantity + 2; ++i)
    {
        mTrnNode->SetChild(i, CreateSphere());
    }

    TriMesh* sphere = StaticCast<TriMesh>(mTrnNode->GetChild(1));
    sphere->LocalTransform.SetTranslate(
        mVertices[mLimitedQuantity - 1] - center);

    // Update the scene, center-and-fit to frustum.
    mScene->Update();
    mTrnNode->LocalTransform.SetTranslate(-mScene->WorldBound.GetCenter());
    APoint camPosition = APoint::ORIGIN -
        2.5f*mScene->WorldBound.GetRadius()*mCamera->GetDVector();
    mCamera->SetPosition(camPosition);

    mCuller.ComputeVisibleSet(mScene);
}
Exemplo n.º 6
0
//----------------------------------------------------------------------------
bool ConvexHull3D::OnKeyDown (unsigned char key, int x, int y)
{
    switch (key)
    {
    // load a new data set
    case 'd':
    case 'D':
        if (++mCurrentFile == mFileQuantity)
        {
            mCurrentFile = 1;
        }

        LoadData();
        return true;

    // query type INT64
    case 'n':
    case 'N':
        mQueryType = Query::QT_INT64;
        strcpy(mHeader, "query type = INT64");
        RegenerateHull();
        return true;

    // query type INTEGER
    case 'i':
    case 'I':
        mQueryType = Query::QT_INTEGER;
        strcpy(mHeader, "query type = INTEGER");
        RegenerateHull();
        return true;

    // query type RATIONAL
    case 'r':
    case 'R':
        mQueryType = Query::QT_RATIONAL;
        strcpy(mHeader, "query type = RATIONAL");
        RegenerateHull();
        return true;

    // query type REAL (float)
    case 'f':
    case 'F':
        mQueryType = Query::QT_REAL;
        strcpy(mHeader, "query type = REAL");
        RegenerateHull();
        return true;

    // query type FILTERED
    case 'c':
    case 'C':
        mQueryType = Query::QT_FILTERED;
        strcpy(mHeader, "query type = FILTERED");
        RegenerateHull();
        return true;

    case 'w':
    case 'W':
        mWireState->Enabled = !mWireState->Enabled;
        return true;

    // Read the notes in ConvexHul3D.h about how to use mLimitedQuantity.
    case '+':
    case '=':
        if (mLimitedQuantity < mNumVertices)
        {
            for (int i = 2; i < mLimitedQuantity + 2; ++i)
            {
                mTrnNode->DetachChildAt(i);
            }
            ++mLimitedQuantity;
            CreateHull();
        }
        return true;
    case '-':
    case '_':
        if (mLimitedQuantity > 3)
        {
            for (int i = 2; i < mLimitedQuantity + 2; ++i)
            {
                mTrnNode->DetachChildAt(i);
            }
            --mLimitedQuantity;
            CreateHull();
        }
        return true;
    }

    return WindowApplication::OnKeyDown(key, x, y);
}
Exemplo n.º 7
0
//----------------------------------------------------------------------------
bool ConvexHull2D::OnKeyDown (unsigned char key, int x, int y)
{
    if (WindowApplication2::OnKeyDown(key, x, y))
    {
        return true;
    }

    switch (key)
    {
    // Generate points that are nearly the same point.
    case '0':
        GenerateHull0D();
        OnDisplay();
        return true;

    // Generate points that are nearly collinear.
    case '1':
        GenerateHull1D();
        OnDisplay();
        return true;

    // Generate points that have a convex polygon hull.
    case '2':
        GenerateHull2D();
        OnDisplay();
        return true;

    // Lots of collinear points that lead to a convex polygon hull.
    case 'l':
    case 'L':
        GenerateHullManyCollinear();
        OnDisplay();
        return true;

    // query type INT64
    case 'n':
    case 'N':
        mQueryType = Query::QT_INT64;
        RegenerateHull();
        OnDisplay();
        return true;

    // query type INTEGER
    case 'i':
    case 'I':
        mQueryType = Query::QT_INTEGER;
        RegenerateHull();
        OnDisplay();
        return true;

    // query type RATIONAL
    case 'r':
    case 'R':
        mQueryType = Query::QT_RATIONAL;
        RegenerateHull();
        OnDisplay();
        return true;

    // query type REAL (float)
    case 'f':
    case 'F':
        mQueryType = Query::QT_REAL;
        RegenerateHull();
        OnDisplay();
        return true;

    // query type FILTERED
    case 'c':
    case 'C':
        mQueryType = Query::QT_FILTERED;
        RegenerateHull();
        OnDisplay();
        return true;
    }

    return false;
}