একটি গোলকের মাঝের অর্ধেকটিকে প্রোগ্রামগতভাবে আঁকুন


10

আমি একটি গোলকের মাঝের অর্ধেকটি তৈরি করার চেষ্টা করছি। মূলত একটি গোলক তৈরি করতে, স্ট্যাক নম্বর এবং স্লাইস নম্বর দেওয়া হয় এবং কতগুলি অগ্রগতি হয় তার জন্য দুটি ভেরিয়েবল phi(টুকরা জন্য) এবং theta(স্ট্যাকের জন্য) দায়ী। এবং প্রক্রিয়াটি নীচের ক্যাপ, বডি এবং শীর্ষ ক্যাপ তৈরিতে বিভক্ত (নীচে দেখানো হয়েছে)। মাঝের অর্ধেক অর্জনের জন্য ( thetaনীচের হিসাবে মাঝারি 50% এর), আমাদের ক্যাপগুলি বাদ দিতে হবে এবং কোনওরকম শরীর পরিবর্তন করতে হবে। আমি স্ট্যাক নম্বর ( 1/4*stackNumbers to 3/4*stackNumbers) এর সাথে চারপাশে খেলছিলাম তবে আমার যে ফলাফলটি চেয়েছিল তা দেয়নি।

মাঝের অর্ধেকটি অর্জনের জন্য আমি কীভাবে গোলকের প্রজন্মকে পরিবর্তন করব pi/4 <theta <pi*3/4? আমার সামগ্রিক সমস্যাটি হল আমি কিভাবে গোলকটি 3 টি বিভিন্ন অংশের উপরের 25%, মাঝারি 50% এবং নীচে 25% বিভক্ত করতে পারি?

প্রোগ্রামিয়ালি গোলক তৈরির জন্য এখানে জনপ্রিয় কোডটি রয়েছে:

এখানে চিত্র বর্ণনা লিখুন

private void generateSphere(int stackNumber, int sliceNumber, boolean facingOut) {
    int capVertexNumber = 3 * sliceNumber;
    int bodyVertexNumber = 4 * sliceNumber * (stackNumber - 2);
    int vertexNumber = (2 * capVertexNumber) + bodyVertexNumber;
    int triangleNumber = (2 * capVertexNumber) + (6 * sliceNumber * (stackNumber - 2));

    vertices = new float[3 * vertexNumber];
    normals = new float[3 * vertexNumber];
    texCoords = new float[2 * vertexNumber];
    indices = new char[triangleNumber];

    // bottom cap
    // createCap(stackNumber, sliceNumber, false, facingOut);

    // body
    createBody(stackNumber, sliceNumber, facingOut);

    // top cap
    createCap(stackNumber, sliceNumber, true, facingOut);
}

private void createCap(int stackNumber, int sliceNumber, boolean top, boolean facingOut) {

    float stackPercentage0;
    float stackPercentage1;

    if (!top) {
        stackPercentage0 = ((float) (stackNumber - 1) / stackNumber);
        stackPercentage1 = 1.0f;

    } else {
        stackPercentage0 = (1.0f / stackNumber);
        stackPercentage1 = 0.0f;
    }

    float t0 = stackPercentage0;
    float t1 = stackPercentage1;
    double theta0 = stackPercentage0 * Math.PI;
    double theta1 = stackPercentage1 * Math.PI;
    double cosTheta0 = Math.cos(theta0);
    double sinTheta0 = Math.sin(theta0);
    double cosTheta1 = Math.cos(theta1);
    double sinTheta1 = Math.sin(theta1);

    for (int slice = 0; slice < sliceNumber; slice++) {
        float slicePercentage0 = ((float) (slice) / sliceNumber);
        float slicePercentage1 = ((float) (slice + 1) / sliceNumber);
        double phi0 = slicePercentage0 * 2.0 * Math.PI;
        double phi1 = slicePercentage1 * 2.0 * Math.PI;
        float s0, s1;
        if (facingOut) {
            s0 = 1 - slicePercentage0;
            s1 = 1 - slicePercentage1;
        } else {
            s0 = slicePercentage0;
            s1 = slicePercentage1;
        }
        float s2 = (s0 + s1) / 2.0f;
        double cosPhi0 = Math.cos(phi0);
        double sinPhi0 = Math.sin(phi0);
        double cosPhi1 = Math.cos(phi1);
        double sinPhi1 = Math.sin(phi1);

        float x0 = (float) (sinTheta0 * cosPhi0);
        float y0 = (float) cosTheta0;
        float z0 = (float) (sinTheta0 * sinPhi0);

        float x1 = (float) (sinTheta0 * cosPhi1);
        float y1 = (float) cosTheta0;
        float z1 = (float) (sinTheta0 * sinPhi1);

        float x2 = (float) (sinTheta1 * cosPhi0);
        float y2 = (float) cosTheta1;
        float z2 = (float) (sinTheta1 * sinPhi0);

        vertices[vertexCount + 0] = x0;
        vertices[vertexCount + 1] = y0;
        vertices[vertexCount + 2] = z0;

        vertices[vertexCount + 3] = x1;
        vertices[vertexCount + 4] = y1;
        vertices[vertexCount + 5] = z1;

        vertices[vertexCount + 6] = x2;
        vertices[vertexCount + 7] = y2;
        vertices[vertexCount + 8] = z2;

        if (facingOut) {
            normals[vertexCount + 0] = x0;
            normals[vertexCount + 1] = y0;
            normals[vertexCount + 2] = z0;

            normals[vertexCount + 3] = x1;
            normals[vertexCount + 4] = y1;
            normals[vertexCount + 5] = z1;

            normals[vertexCount + 6] = x2;
            normals[vertexCount + 7] = y2;
            normals[vertexCount + 8] = z2;
        } else {
            normals[vertexCount + 0] = -x0;
            normals[vertexCount + 1] = -y0;
            normals[vertexCount + 2] = -z0;

            normals[vertexCount + 3] = -x1;
            normals[vertexCount + 4] = -y1;
            normals[vertexCount + 5] = -z1;

            normals[vertexCount + 6] = -x2;
            normals[vertexCount + 7] = -y2;
            normals[vertexCount + 8] = -z2;
        }

        texCoords[texCoordCount + 0] = s0;
        texCoords[texCoordCount + 1] = t0;
        texCoords[texCoordCount + 2] = s1;
        texCoords[texCoordCount + 3] = t0;
        texCoords[texCoordCount + 4] = s2;
        texCoords[texCoordCount + 5] = t1;

        if ((facingOut && top) || (!facingOut && !top)) {
            indices[indexCount + 0] = (char) (triangleCount + 1);
            indices[indexCount + 1] = (char) (triangleCount + 0);
            indices[indexCount + 2] = (char) (triangleCount + 2);
        } else {
            indices[indexCount + 0] = (char) (triangleCount + 0);
            indices[indexCount + 1] = (char) (triangleCount + 1);
            indices[indexCount + 2] = (char) (triangleCount + 2);
        }

        vertexCount += 9;
        texCoordCount += 6;
        indexCount += 3;
        triangleCount += 3;
    }

}

private void createBody(int stackNumber, int sliceNumber, boolean facingOut) {
    for (int stack = 1; stack < stackNumber - 1; stack++) {
        float stackPercentage0 = ((float) (stack) / stackNumber);
        float stackPercentage1 = ((float) (stack + 1) / stackNumber);

        float t0 = stackPercentage0;
        float t1 = stackPercentage1;

        double theta0 = stackPercentage0 * Math.PI;
        double theta1 = stackPercentage1 * Math.PI;
        double cosTheta0 = Math.cos(theta0);
        double sinTheta0 = Math.sin(theta0);
        double cosTheta1 = Math.cos(theta1);
        double sinTheta1 = Math.sin(theta1);

        for (int slice = 0; slice < sliceNumber; slice++) {
            float slicePercentage0 = ((float) (slice) / sliceNumber);
            float slicePercentage1 = ((float) (slice + 1) / sliceNumber);
            double phi0 = slicePercentage0 * 2.0 * Math.PI;
            double phi1 = slicePercentage1 * 2.0 * Math.PI;
            float s0, s1;
            if (facingOut) {
                s0 = 1.0f - slicePercentage0;
                s1 = 1.0f - slicePercentage1;
            } else {
                s0 = slicePercentage0;
                s1 = slicePercentage1;
            }
            double cosPhi0 = Math.cos(phi0);
            double sinPhi0 = Math.sin(phi0);
            double cosPhi1 = Math.cos(phi1);
            double sinPhi1 = Math.sin(phi1);

            float x0 = (float) (sinTheta0 * cosPhi0);
            float y0 = (float) cosTheta0;
            float z0 = (float) (sinTheta0 * sinPhi0);

            float x1 = (float) (sinTheta0 * cosPhi1);
            float y1 = (float) cosTheta0;
            float z1 = (float) (sinTheta0 * sinPhi1);

            float x2 = (float) (sinTheta1 * cosPhi0);
            float y2 = (float) cosTheta1;
            float z2 = (float) (sinTheta1 * sinPhi0);

            float x3 = (float) (sinTheta1 * cosPhi1);
            float y3 = (float) cosTheta1;
            float z3 = (float) (sinTheta1 * sinPhi1);

            vertices[vertexCount + 0] = x0;
            vertices[vertexCount + 1] = y0;
            vertices[vertexCount + 2] = z0;

            vertices[vertexCount + 3] = x1;
            vertices[vertexCount + 4] = y1;
            vertices[vertexCount + 5] = z1;

            vertices[vertexCount + 6] = x2;
            vertices[vertexCount + 7] = y2;
            vertices[vertexCount + 8] = z2;

            vertices[vertexCount + 9] = x3;
            vertices[vertexCount + 10] = y3;
            vertices[vertexCount + 11] = z3;

            if (facingOut) {
                normals[vertexCount + 0] = x0;
                normals[vertexCount + 1] = y0;
                normals[vertexCount + 2] = z0;

                normals[vertexCount + 3] = x1;
                normals[vertexCount + 4] = y1;
                normals[vertexCount + 5] = z1;

                normals[vertexCount + 6] = x2;
                normals[vertexCount + 7] = y2;
                normals[vertexCount + 8] = z2;

                normals[vertexCount + 9] = x3;
                normals[vertexCount + 10] = y3;
                normals[vertexCount + 11] = z3;
            } else {
                normals[vertexCount + 0] = -x0;
                normals[vertexCount + 1] = -y0;
                normals[vertexCount + 2] = -z0;

                normals[vertexCount + 3] = -x1;
                normals[vertexCount + 4] = -y1;
                normals[vertexCount + 5] = -z1;

                normals[vertexCount + 6] = -x2;
                normals[vertexCount + 7] = -y2;
                normals[vertexCount + 8] = -z2;

                normals[vertexCount + 9] = -x3;
                normals[vertexCount + 10] = -y3;
                normals[vertexCount + 11] = -z3;
            }

            texCoords[texCoordCount + 0] = s0;
            texCoords[texCoordCount + 1] = t0;
            texCoords[texCoordCount + 2] = s1;
            texCoords[texCoordCount + 3] = t0;
            texCoords[texCoordCount + 4] = s0;
            texCoords[texCoordCount + 5] = t1;
            texCoords[texCoordCount + 6] = s1;
            texCoords[texCoordCount + 7] = t1;

            // one quad looking from outside toward center
            //
            // @formatter:off
            //
            // s1 --> s0
            //
            // t0 1-----0
            // | | |
            // v | |
            // t1 3-----2
            //
            // @formatter:on
            //
            // Note that tex_coord t increase from top to bottom because the
            // texture image is loaded upside down.
            if (facingOut) {
                indices[indexCount + 0] = (char) (triangleCount + 0);
                indices[indexCount + 1] = (char) (triangleCount + 1);
                indices[indexCount + 2] = (char) (triangleCount + 2);

                indices[indexCount + 3] = (char) (triangleCount + 2);
                indices[indexCount + 4] = (char) (triangleCount + 1);
                indices[indexCount + 5] = (char) (triangleCount + 3);
            } else {
                indices[indexCount + 0] = (char) (triangleCount + 0);
                indices[indexCount + 1] = (char) (triangleCount + 2);
                indices[indexCount + 2] = (char) (triangleCount + 1);

                indices[indexCount + 3] = (char) (triangleCount + 2);
                indices[indexCount + 4] = (char) (triangleCount + 3);
                indices[indexCount + 5] = (char) (triangleCount + 1);
            }

            vertexCount += 12;
            texCoordCount += 8;
            indexCount += 6;
            triangleCount += 4;
        }
    }

} 

উত্তর:


1

রিং দ্বারা গঠিত আপনার গোলকের সাথে পরীক্ষার ক্ষেত্রে আপনার প্রশ্নটি ভাবেন। যদি আপনার 5 এর টেসলেসন ফ্যাক্টর থাকে তবে আপনার কাছে শীর্ষ টুপি, 2 টি মাঝারি বিভাগ এবং নীচের অংশটি থাকবে। নীচের দুটি টেসেললেশন রিংটি 25% নীচের ক্যাপ এবং শীর্ষ টেসেলসেলেশন দুটি 25% শীর্ষ ক্যাপটি রিং করে। কেন্দ্রটি তাই নিরক্ষীয় অঞ্চলে একটি রিং যার উভয় পাশে 50% এ মুখের সেট রয়েছে। এখানে প্রতিটি উচ্চতায় রিংগুলি প্রথমে গণনা করে এবং তারপরে প্রতিটি রিংয়ের মধ্যে মুখ উত্পন্ন করে একটি গোলককে কীভাবে পরীক্ষা করা যায় তার একটি নমুনা এখানে।

float radius = 1.0f;
const int tesselationFactor = 5;

for (int i = 0; i <= tesselationFactor; i++)
{
    const float PI = 3.14159265359f;
    const float PIDIV2 = PI / 2.0f;

    // find height of ring
    float height = (i*PI / tesselationFactor) - PIDIV2;
    float dy = sinf(height);
    float theta = cosf(height);

    // locate verticies equally around center to form a ring
    for (int j = 0; j <= tessellation * 2; j++)
    {

        float longitude = static_cast<float>(j) * PIDIV2 / (tessellation * 2);
        float dx = sinf(longitude) * theta;
        float dz = cosf(longitude) * theta;

        Vector normal{ dx, dy, dz }; // initialize vector
        vertices.push_back(VertexPositionNormal(normal * radius, normal));
    }
}
// Fill the index buffer with triangles joining each pair of latitude rings.
int stride = tessellation * 2 + 1;
for (int i = 0; i < tesselationFactor; i++) // verticle rings
{
    for (int j = 0; j <= tessellation * 2; j++) // horizontal verticies
    {
        // 
        int i1 = i + 1;
        int j1 = (j + 1) % stride;
        /* connecting face */
         // triangle 1
        index_push_back(indices, i * stride + j);
        index_push_back(indices, i1 * stride + j);
        index_push_back(indices, i * stride + j1);
         // triangle 2
        index_push_back(indices, i * stride + j1);
        index_push_back(indices, i1 * stride + j);
        index_push_back(indices, i1 * stride + j1);
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.