Défectueux code C # impliquant doubles et entiers
Question
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();
}
Quelqu'un peut-il voir des problèmes immédiats avec ce code?
Les variables tr
et tb
toujours évalués à 0.
Je suis heureux de vous fournir plus d'informations si elle est nécessaire.
La solution
Vous avez pas donné les types pour les autres variables - en particulier, quels sont les types de camera.fov_x
et camera.fov_y
? S'ils sont tous les deux entiers, puis seront évalués les lignes et angx
angy
d'initialisation en utilisant l'arithmétique entier.
Cela peut être corrigé par coulée un des opérandes:
double angy = ((double) camera.fov_y / h) * iy;
Les variables fovy
et fovx
sont déjà se double cependant, ce n'est pas le problème.
Pourriez-vous donner un exemple complet de ce que nous pouvons compiler et tester nous-mêmes?
EDIT: l'édition de Koistya Navin est surpuissant. Vous avez seulement besoin d'un opérande d'une expression à un double pour la chose à calculer en utilisant le double arithmétique. (Il doit être l'expression juste si -. Si vous faites (a/b) * c
et coulé c
double, la multiplication se fera avec double arithmétique, mais a / b peut encore être fait sous forme d'entiers)
Voici la liste changé de façon appropriée pour faire l'arithmétique que double est utilisé partout où il devrait être:
// 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();
}
Autres conseils
Il sait qu'il ne fait pas partie de votre question initiale, mais en utilisant SetPixel (..) n'est pas très efficace et pourrait être un problème si vous prévoyez de l'utiliser dans un moteur de traçage de rayon.
Vous pouvez utiliser la méthode LockBits (), voir cette réponse et celui-ci pour plus de détails. Ils autre façon de faire est d'accéder aux données en utilisant le code C # « dangereux », qui vous permet d'utilisations des pointeurs vers les données. Voir cette question pour plus d'informations, je suis un ~ x2 vitesse par l'aide " code non sécurisé ».
Ne pas oublier de jeter vos entiers en double. Par exemple:
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();
}
Référence rapide:
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