//----------------------------------------------------------------------------
Delaunay2DWindow::Delaunay2DWindow(Parameters& parameters)
    :
    Window(parameters),
    mTextColor(0.0f, 0.0f, 0.0f, 1.0f),
    mCurrentTriX(-1),
    mCurrentTriY(-1),
    mCurrentIndex(0)
{
#if 1
    // Randomly generated points.
    std::mt19937 mte;
    std::uniform_real_distribution<float> rnd(0.125f, 0.875f);
    mVertices.resize(256);
    for (auto& v : mVertices)
    {
        v[0] = mXSize*rnd(mte);
        v[1] = mYSize*rnd(mte);
    }
#endif

#if 0
    // A 3x3 square grid.
    mVertices.resize(9);
    mVertices[0] = Vector2<float>( 64.0f,  64.0f);
    mVertices[1] = Vector2<float>( 64.0f, 256.0f);
    mVertices[2] = Vector2<float>( 64.0f, 448.0f);
    mVertices[3] = Vector2<float>(256.0f,  64.0f);
    mVertices[4] = Vector2<float>(256.0f, 256.0f);
    mVertices[5] = Vector2<float>(256.0f, 448.0f);
    mVertices[6] = Vector2<float>(448.0f,  64.0f);
    mVertices[7] = Vector2<float>(448.0f, 256.0f);
    mVertices[8] = Vector2<float>(448.0f, 448.0f);
#endif

    mDelaunay(static_cast<int>(mVertices.size()), &mVertices[0], 0.001f);
    if (mDelaunay.GetDimension() == 2)
    {
        mDelaunay.GetHull(mHull);
    }
    else
    {
        LogError("Degenerate point set.");
        parameters.created = false;
        return;
    }

    mInfo.initialTriangle = -1;
    mInfo.finalTriangle = 0;

    mOverlay.reset(new OverlayEffect(mXSize, mYSize, mXSize, mYSize,
        SamplerState::MIN_P_MAG_P_MIP_P, SamplerState::CLAMP,
        SamplerState::CLAMP, true));

    mScreenTexture.reset(new Texture2(DF_R8G8B8A8_UNORM, mXSize, mYSize));
    mScreenTexture->SetUsage(Resource::DYNAMIC_UPDATE);
    mOverlay->SetTexture(mScreenTexture);
    mScreenTexels = mScreenTexture->Get<unsigned int>();
}
ConstrainedDelaunay2DWindow::ConstrainedDelaunay2DWindow(
    Parameters& parameters)
    :
    Window(parameters),
    mTextColor({ 0.0f, 0.0f, 0.0f, 1.0f }),
    mCurrentTriX(-1),
    mCurrentTriY(-1),
    mCurrentIndex(0)
{
    // Randomly generated points.
    std::mt19937 mte;
    std::uniform_real_distribution<float> rnd(0.125f, 0.875f);
    mVertices.resize(256);
    for (auto& v : mVertices)
    {
        v[0] = mXSize*rnd(mte);
        v[1] = mYSize*rnd(mte);
    }

    int numVertices = static_cast<int>(mVertices.size());
    mDelaunay(numVertices, &mVertices[0], 0.001f);

    if (mDelaunay.GetDimension() == 2)
    {
        mDelaunay.GetHull(mHull);
    }
    else
    {
        LogError("Degenerate point set.");
        parameters.created = false;
        return;
    }

    mInfo.initialTriangle = -1;
    mInfo.finalTriangle = 0;

    mOverlay = std::make_shared<OverlayEffect>(mProgramFactory, mXSize,
        mYSize, mXSize, mYSize, SamplerState::MIN_P_MAG_P_MIP_P,
        SamplerState::CLAMP, SamplerState::CLAMP, true);

    mScreenTexture = std::make_shared<Texture2>(DF_R8G8B8A8_UNORM, mXSize,
        mYSize);
    mScreenTexture->SetUsage(Resource::DYNAMIC_UPDATE);
    mOverlay->SetTexture(mScreenTexture);
    mScreenTexels = mScreenTexture->Get<unsigned int>();
}
Exemple #3
0
bool Delaunay3DWindow::CreateScene()
{
#if 1
    // Randomly generated points in the cube [-1,1]^3.  (0,0,0) is added to
    // ensure the hull contains the origin and the virtual trackball display
    // appears centered.
    std::mt19937 mte;
    std::uniform_real_distribution<float> rnd(-1.0f, 1.0f);
    mVertices.resize(128);
    for (auto& v : mVertices)
    {
        for (int j = 0; j < 3; ++j)
        {
            v[j] = rnd(mte);
        }
    }
    mVertices[0] = Vector3<float>::Zero();
#endif

#if 0
    // A cube with 3x3x3 points.
    mVertices.resize(27);
    for (int z = 0, i = 0; z < 3; ++z)
    {
        float fz = z - 1.0f;
        for (int y = 0; y < 3; ++y)
        {
            float fy = y - 1.0f;
            for (int x = 0; x < 3; ++x, ++i)
            {
                float fx = x - 1.0f;
                mVertices[i] = Vector3<float>(fx, fy, fz);
            }
        }
    }
#endif

#if 0
    // Some pathological examples (needle-like configurations).
    //std::string filename = "data1.txt";
    std::string filename = "data2.txt";
    //std::string filename = "data3.txt";

    std::string path = mEnvironment.GetPath(filename);
    if (path == "")
    {
        LogError("Cannot find file " + filename + ".");
        return false;
    }

    std::ifstream input(path);
    int numVertices;
    input >> numVertices;
    mVertices.resize(numVertices);
    for (int i = 0; i < numVertices; ++i)
    {
        for (int j = 0; j < 3; ++j)
        {
            input >> mVertices[i][j];
        }
    }
#endif

    Vector3<float> vmin, vmax;
    ComputeExtremes((int)mVertices.size(), &mVertices[0], vmin, vmax);
    for (int j = 0; j < 3; ++j)
    {
        mRandom[j] = std::uniform_real_distribution<float>(vmin[j], vmax[j]);
    }

    mDelaunay(static_cast<int>(mVertices.size()), &mVertices[0], 0.001f);
    mInfo.initialTetrahedron = -1;
    mInfo.finalTetrahedron = 0;

    mWireTetra.resize(mDelaunay.GetNumTetrahedra());
    mSolidTetra.resize(mDelaunay.GetNumTetrahedra());

    mScene = std::make_shared<Node>();
    CreateSphere();
    mVCEffect = std::make_shared<VertexColorEffect>(mProgramFactory);
    for (int j = 0; j < mDelaunay.GetNumTetrahedra(); ++j)
    {
        CreateTetra(j);
    }
    mCameraRig.Subscribe(mWireTetra[0]->worldTransform,
        mVCEffect->GetPVWMatrixConstant());

    mTrackball.Attach(mScene);
    mTrackball.Update();
    return true;
}
Exemple #4
0
std::vector<Triangle> triangulate(const std::vector<Vec2f> & points, float resolution = 50.0f)
{
	std::vector<Triangle> mTriangles;
	std::vector<Vec2f> mPoints = points;
	float mSize = mPoints.size();
	float mCount = fMIN(resolution, mSize);
	tpp::Delaunay::Point mPoint;
	std::vector<tpp::Delaunay::Point> mVertices;
	for (int32_t i = 0; i < mCount; i++) {
		int32_t mId = (int32_t)((float)i / mCount * mSize);
		mPoint[0] = mPoints[mId].x;
		mPoint[1] = mPoints[mId].y;
		mVertices.push_back(mPoint);
	}
	tpp::Delaunay mDelaunay(mVertices);
	mDelaunay.Triangulate();
	for (tpp::Delaunay::fIterator mTriIt = mDelaunay.fbegin(); mTriIt != mDelaunay.fend(); ++mTriIt) {
		int32_t mA = mDelaunay.Org(mTriIt);
		int32_t mB = mDelaunay.Dest(mTriIt);
		int32_t mC = mDelaunay.Apex(mTriIt);
		int32_t mAId = (int32_t)(((float)mA / resolution) * mSize);
		int32_t mBId = (int32_t)(((float)mB / resolution) * mSize);
		int32_t mCId = (int32_t)(((float)mC / resolution) * mSize);
		Vec2f mTriangle[3];
		mTriangle[0] = Vec2f(mPoints[mAId].x, mPoints[mAId].y);
		mTriangle[1] = Vec2f(mPoints[mBId].x, mPoints[mBId].y);
		mTriangle[2] = Vec2f(mPoints[mCId].x, mPoints[mCId].y);
		Vec2f mCentroid = Vec2f(
				(mTriangle[0].x + mTriangle[1].x + mTriangle[2].x) / 3.0f,
				(mTriangle[0].y + mTriangle[1].y + mTriangle[2].y) / 3.0f
			);
		int32_t mCounter = 0;
		Vec2f mPointA = mPoints[0];
		Vec2f mPointB;
		for (int32_t i = 1; i < (int32_t)mSize; i++) {
			mPointB = mPoints[i];
			if (mCentroid.y > fMIN(mPointA.y, mPointB.y) &&
					mCentroid.y <= fMAX(mPointA.y, mPointB.y) &&
					mCentroid.x <= fMAX(mPointA.x, mPointB.x) &&
					mPointA.y != mPointB.y &&
					(mPointA.x == mPointB.x || mCentroid.x <= (mCentroid.y - mPointA.y) * (mPointB.x - mPointA.x) / (mPointB.y - mPointA.y) + mPointA.x))
				mCounter++;
			mPointA = mPointB;
		}
		if (mCounter % 2 != 0) {
			Triangle mTriData;
			float x0 = mTriangle[0].x;
			float y0 = mTriangle[0].y;
			float x1 = mTriangle[1].x;
			float y1 = mTriangle[1].y;
			float x2 = mTriangle[2].x;
			float y2 = mTriangle[2].y;
			if (((x1 - x0) * (y2 - y0) - (x2 -x0) * (y1 - y0)) > 0) {
				mTriData.a = Vec2f(x0, y0);
				mTriData.b = Vec2f(x1, y1);
				mTriData.c = Vec2f(x2, y2);
			} else {
				mTriData.a = Vec2f(x0, y0);
				mTriData.b = Vec2f(x2, y2);
				mTriData.c = Vec2f(x1, y1);
			}
			mTriangles.push_back(mTriData);
		}
	}
	return mTriangles;
}