سؤال

    for (iy = 0; iy < h; iy++)
    {
        double angy = (camera.fov_y / h) * iy;
        for (ix = 0; ix < w; ix++)
        {
            double angx = (camera.fov_x / w) * ix;
            //output[ix,iy].r = (int)Math.Round(255 * (angy / camera.fov_y);
            //output[ix,iy].b = (int)Math.Round(255 * (angy / camera.fov_y); 
            double tr = (angx / camera.fov_x) * 255D;
            double tb = (angy / camera.fov_y) * 255D;
            Console.Write("({0},{1})",Math.Round(tr),Math.Round(tb));

            output.SetPixel(ix, iy, Color.FromArgb(Convert.ToInt32(tr), 0, Convert.ToInt32(tb)) );
            Console.Write(".");
        }
        Console.WriteLine();
    }

هل يمكن لأي شخص أن يرى أي مشاكل فورية مع هذا الرمز؟ المتغيرات tr و tb دائما تقييم إلى 0.

أنا سعيد بتقديم المزيد من المعلومات إذا كانت هناك حاجة إليها.

هل كانت مفيدة؟

المحلول

لم تعط الأنواع من المتغيرات الأخرى - على وجه الخصوص، ما هي أنواع camera.fov_x و camera.fov_yب إذا كانوا على حد سواء أعداد صحيحة، فسيتم تهيئة الخطوط angx و angy سيتم تقييمها باستخدام الحساب الصحيحة.

يمكن إصلاح ذلك عن طريق صب إحدى المعاملات:

double angy = ((double) camera.fov_y / h) * iy;

ال fovy و fovx المتغيرات تتضاعف بالفعل، هذه ليست هي المشكلة.

هل يمكن أن تعطي مثالا كاملا على هذا، والذي يمكننا ترجمةه واختبر أنفسنا؟

تحرير: تحرير Koistya Navin هو مبالغة. تحتاج فقط إلى معامل واحد من التعبير ليكون مزدوجا لحساب كل شيء باستخدام حسابي مزدوج. (يجب أن يكون التعبير الصحيح رغم ذلك - إذا قمت بذلك (a/b) * c و cast. c مزدوج، وسيتم الانتهاء من الضرب بحساب مزدوج ولكن A / B قد لا يزال يحدث كعضات صحيحة.)

هنا تم تغيير القائمة بشكل مناسب للتأكد من استخدام الحساب المزدوج في كل مكان يجب أن يكون:

// Changed loops to declare the variable, for stylistic purposes
for (int iy = 0; iy < h; iy++)
{
    // Changed here - cast camera.fov_y
    double angy = ((double) camera.fov_y / h) * iy;
    for (int ix = 0; ix < w; ix++)
    {
        // Changed here - cast camera.fov_x
        double angx = ((double) camera.fov_x / w) * ix;
        //output[ix,iy].r = (int)Math.Round(255 * (angy / camera.fov_y);
        //output[ix,iy].b = (int)Math.Round(255 * (angy / camera.fov_y); 
        double tr = (angx / camera.fov_x) * 255D;
        double tb = (angy / camera.fov_y) * 255D;
        Console.Write("({0},{1})", Math.Round(tr), Math.Round(tb));

        output.SetPixel(ix, iy, Color.FromArgb(Convert.ToInt32(tr), 
                                               0,
                                               Convert.ToInt32(tb)) );
        Console.Write(".");
    }
    Console.WriteLine();
}

نصائح أخرى

إنه يعرف أنه ليس جزءا من سؤالك الأصلي، ولكن باستخدام SetPixel (..) ليس فعالا للغاية ويمكن أن يكون مشكلة إذا كنت تخطط لاستخدامه في محرك راي.

قد ترغب في استخدام طريقة Lockbits ()، راجع هذا إجابه و هذا لمزيد من التفاصيل. إنهم بطريقة أخرى للذهاب هو الوصول إلى البيانات باستخدام رمز "غير آمن" C #، والذي يسمح لك باستخدام مؤشرات إلى البيانات. يرى هذا السؤال لمزيد من المعلومات، حصلت على سرعة ~ x2 باستخدام رمز "غير آمن".

لا تنس أن يلقي الأعداد الصحيحة الخاصة بك للتضاعف. علي سبيل المثال:

for (iy = 0; iy < h; iy++)
{
    double angy = ((double) camera.fov_y / h) * iy;
    for (ix = 0; ix < w; ix++)
    {
        double angx = ((double) camera.fov_x / (double) w) * (double) ix;
        output[ix,iy].r = (int) Math.Round(255 * (angy / camera.fov_y);
        output[ix,iy].b = (int) Math.Round(255 * (angy / camera.fov_y);
        double tr = (angx / camera.fov_x) * 255D;
        double tb = (angy / camera.fov_y) * 255D;
        Console.Write("({0},{1})",Math.Round(tr), Math.Round(tb));
        output.SetPixel(ix, iy, Color.FromArgb(
            Convert.ToInt32(tr), 0, Convert.ToInt32(tb)) );
        Console.Write(".");
    }
    Console.WriteLine();
} 

مرجع سريع:

 int * double = double
 int / double = double
 double * int = double
 double / int = double

 int * int = int
 int / int = int // be carefull here!

 1 / 10 = 0 (not 0.1D)
 10 / 11 = 0 (not 1)
 1D / 10 = 0.1D
 1 / 10D = 0.1D
 1D / 10D = 0.1D
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top