Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 26.11.2011, 19:01   #1
nXs
Форумчанин
 
Регистрация: 26.02.2010
Сообщений: 126
По умолчанию Значение NAN

Здравствуйте, появилась проблема, есть кусок кода который генерирует нормали к поверхности, раньше он работал на ура, он никак не изменялся, в один прекрасный момент перестал работать нормально, при трасировке выяснилось что переменная принимает значение NAN, что это за значение, когда оно появляется и как его победить?
nXs вне форума Ответить с цитированием
Старый 26.11.2011, 19:06   #2
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

NAN = Not A Number

> когда оно появляется и как его победить

ищите ошибку при работе с плавающей точкой.
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Старый 26.11.2011, 19:11   #3
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 19,042
По умолчанию

Ноль на ноль разделите и получите в Double NAN
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 26.11.2011, 19:16   #4
nXs
Форумчанин
 
Регистрация: 26.02.2010
Сообщений: 126
По умолчанию

Спасибо за ответ, но волнует вопрос, почему эта г...сть полявилась, код ведь не менялся, и кстати появилось после введения мультитекстурирования и изменения текстуры в реалтайме (но эт никак не связано с нормалями), и при этом при некоторых операциях полезли access violation хотя их раньше не было, возможлно ли что это из за использования динамических масивов (тип переполнения памяти или еще какой нибудь ерунды)?
nXs вне форума Ответить с цитированием
Старый 26.11.2011, 19:32   #5
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

> возможлно ли что это

да, возможно. Так же, как возможно по тысяче других причин. Не видя конкретного кода, места ошибки и прочего можно только давать общие советы.
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Старый 26.11.2011, 19:35   #6
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 19,042
По умолчанию

access violation очень часто при выходе за пределы массива или при обращении к удаленному объекту. Если прога после этого не завершается, то возможны наведенные ошибки любого характера. Наверно прежде всего на access violation нужно сконцетрироваться
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 26.11.2011, 20:48   #7
nXs
Форумчанин
 
Регистрация: 26.02.2010
Сообщений: 126
По умолчанию

Ну что ж , извините за большое количество кода, и так, код который вызывает access violation (не сразу, а после нескольких вызовов процедуры ComboBox6Change):
Код:
procedure TLEForm.ComboBox6Change(Sender: TObject);
var
b:TBitmap;
i,j:integer;
begin
if not fileExists(ExtractFileDir(paramStr(0))+'\Brushes\'+ComboBox11.Text+'\'+ComboBox6.Text+'.tga') then   exit;

if Length(TrnBrush.Map.Data)>0 then
begin
for i:=0 to
TrnBrush.Map.Height-1 do
Finalize(TrnBrush.Map.Data[i]);
Finalize(TrnBrush.Map.Data);
end;

NTrackBar1.Position:=3;
if not LoadTGA(ExtractFileDir(paramStr(0))+'\Brushes\'+ComboBox11.Text+'\'+ComboBox6.Text+'.tga',3,TrnBrush.Map) then exit;


if Image2.Picture.Graphic=nil then
Image2.Picture.Graphic:=TBitmap.Create;

b:=TBitmap.Create;
b.Width:=TrnBrush.Map.Width;
B.Height:=TrnBrush.Map.Height;

NEDIT4.Text:=inttostr(TrnBrush.Map.Width);
NEDIT5.Text:=inttostr(TrnBrush.Map.Height);


for i:=0 to TrnBrush.Map.Height-1 do
for j:=0 to TrnBrush.Map.Width-1 do
B.Canvas.Pixels[i,TrnBrush.Map.Width-1-j]:=RGB(TrnBrush.Map.Data[i,j][0],TrnBrush.Map.Data[i,j][1],TrnBrush.Map.Data[i,j][2]);

Image2.Picture.Graphic.Assign(B);
Image2.Refresh;
B.Destroy;

TrnBrush.RadiusH:=trunc(TrnBrush.Map.Height/2);
TrnBrush.RadiusW:=trunc(TrnBrush.Map.Width/2);
end;
nXs вне форума Ответить с цитированием
Старый 26.11.2011, 20:49   #8
nXs
Форумчанин
 
Регистрация: 26.02.2010
Сообщений: 126
По умолчанию

Код:
function LoadTGA(Name:string;Scale:integer;var Map:TTGAStream):boolean;

function SplitNum(AHigh, ALow: Byte): Integer;
begin
  Result := AHigh shl 8 or ALow;
end;

var
FInfo:TGAInfo;
Css:TCompressHeader;
F:TMemoryStream;
i,n,k,j:integer;
R,G,B,A:Byte;


Texture:array  of Byte;

Size,Width,height : Integer;
begin

F:=TMemoryStream.Create;
F.LoadFromFile(Name);
F.ReadBuffer(FInfo,sizeof(FInfo));

Width:=SplitNum(FInfo.Width[1], FInfo.Width[0]);
Height:=SplitNum(FInfo.Height[1], FInfo.Height[0]);
Map.Width:=Width;
Map.Height:=Height;

Size:=width*height;

case FInfo.DataType of
2:begin
if FInfo.Bpp=32 then
begin
Size:=Size*4;
SetLength(Texture,size);
i:=0;
while i<size do
begin
 F.Read(Texture[i+2],sizeof(byte));                       //ALPHA!!!
 F.Read(Texture[i+1],sizeof(byte));
 F.Read(Texture[i],sizeof(byte));
 F.Read(Texture[i+3],sizeof(byte));
 inc(i,4);
end;
end else
begin
Size:=Size*3;
i:=0;
SetLength(Texture,size);
while i<size do
begin
 F.Read(Texture[i+2],sizeof(byte));
 F.Read(Texture[i+1],sizeof(byte));
 F.Read(Texture[i],sizeof(byte));
 inc(i,3);
end;
end;
end;
10:                                                  //Чтение Запакованого RLE TGA

if FInfo.Bpp=32 then
begin                                             //Чтение RLE TGA с ALPHA
i:=0;
Size:=Size*4;
SetLength(Texture,size);

n:=Width*Height;
while n>0 do
begin
F.Read(Css.BlockInfo,sizeOf(Byte));
Css.Compressed:=Css.BlockInfo and 128;
Css.PixelsCount:=Css.BlockInfo and 127;

case Css.Compressed Of
0:begin    {unpacked Data}
for k:=0 to Css.PixelsCount do
begin
    F.Read(Texture[i+2],sizeof(byte));
    F.Read(Texture[i+1],sizeof(byte));                       //ALPHA
    F.Read(Texture[i],sizeof(byte));
    F.Read(Texture[i+3],sizeof(byte));
    inc(i,4);
    n:=n-1;
end;
  end;
128:begin     {packed data}
      F.Read(B,sizeof(byte));
      F.Read(G,sizeof(byte));
      F.Read(R,sizeof(byte));
      F.Read(A,sizeof(byte));
      for k:=0 to Css.PixelsCount do
        begin
          Texture[i]:=R;
          Texture[i+1]:=G;
          Texture[i+2]:=B;
          Texture[i+3]:=A;
          inc(i,4);
        end;


      n:=n-1;
    end;
  end;
end;{case}

end else

...
nXs вне форума Ответить с цитированием
Старый 26.11.2011, 20:50   #9
nXs
Форумчанин
 
Регистрация: 26.02.2010
Сообщений: 126
По умолчанию

пордолжение
Код:
...

begin                                 //Чтение RLE TGA без ALPHA
i:=0;
n:=Width*Height;
Size:=Size*3;
SetLength(Texture,size);

while n>0 do
begin
F.Read(Css.BlockInfo,sizeOf(Byte));
Css.Compressed:=Css.BlockInfo and 128;
Css.PixelsCount:=Css.BlockInfo and 127;

case Css.Compressed Of
0:begin    {unpacked Data}
for k:=0 to Css.PixelsCount do
    begin
      F.Read(Texture[i+2],sizeof(byte));
      F.Read(Texture[i+1],sizeof(byte));
      F.Read(Texture[i],sizeof(byte));


      inc(i,3);

      n:=n-1;
    end;
  end;
128:begin     {packed data}
      F.Read(B,sizeof(byte));
      F.Read(G,sizeof(byte));
      F.Read(R,sizeof(byte));

      for k:=0 to Css.PixelsCount do
      begin
      Texture[i]:=R;
      Texture[i+1]:=G;
      Texture[i+2]:=B;
      inc(i,3);
      n:=n-1;
      end;
    end;
end;{case}

end;
end;

end;{Main Case}

F.Destroy;
n:=0;

case Scale of
  1:begin
      Map.Height:=trunc(Map.Height/4);
      Map.Width:=trunc(Map.Width/4);
      SeTLength(Map.Data,Map.Height);
      for i:=0 to Map.Height-1 do
      SetLength(Map.Data[i],Map.Width);

      for i:=0 to MAp.Height-1 do
      begin
        for j:=0 to Map.width-1 do
        begin
          Map.Data[i,j][0]:=Texture[n];
          inc(n);
          Map.Data[i,j][1]:=Texture[n];
          inc(n);
          Map.Data[i,j][2]:=Texture[n];
          inc(n);

          if FInfo.Bpp=32 then
            begin
              Map.Data[i,j][3]:=Texture[n];
              inc(n,4);
            end;
          inc(n,9);
        end;
        if FInfo.Bpp=32 then inc(n,(Map.Width)*48) else
        inc(n,(Map.Width)*36);
      end;
    end;

  2:begin
      Map.Height:=trunc(Map.Height/2);
      Map.Width:=trunc(Map.Width/2);
      SeTLength(Map.Data,Map.Height);
      for i:=0 to Map.Height-1 do
      SetLength(Map.Data[i],Map.Width);

      for i:=0 to MAp.Height-1 do
      begin
        for j:=0 to Map.width-1 do
        begin
          Map.Data[i,j][0]:=Texture[n];
          inc(n);
          Map.Data[i,j][1]:=Texture[n];
          inc(n);
          Map.Data[i,j][2]:=Texture[n];
          inc(n);

          if FInfo.Bpp=32 then
            begin
              Map.Data[i,j][3]:=Texture[n];
              inc(n,2);
            end;
          inc(n,3);
        end;
        if FInfo.Bpp=32 then inc(n,(Map.Width)*8) else
        inc(n,(Map.Width)*6);
      end;
    end;
  3:begin
      SeTLength(Map.Data,Map.Height);
      for i:=0 to Map.Height-1 do
      SetLength(Map.Data[i],Map.Width);

      for i:=0 to MAp.Height-1 do
      for j:=0 to Map.width-1 do
      begin
        Map.Data[i,j][0]:=Texture[n];
        inc(n);
        Map.Data[i,j][1]:=Texture[n];
        inc(n);
        Map.Data[i,j][2]:=Texture[n];
        inc(n);

        if FInfo.Bpp=32 then
          begin
            Map.Data[i,j][3]:=Texture[n];
            inc(n);
          end;
      end;
    end;

    4:begin
      Map.Height:=Map.Height*2;
      Map.Width:=Map.Width*2;
      SeTLength(Map.Data,Map.Height);
      for i:=0 to Map.Height-1 do
      SetLength(Map.Data[i],Map.Width);

      i:=0;
      j:=0;

      while i<MAp.Height-1 do
      begin
      while j<Map.width-1 do
      begin
        Map.Data[i,j][0]:=Texture[n];
        Map.Data[i,j+1][0]:=Texture[n];
        Map.Data[i+1,j][0]:=Texture[n];
        Map.Data[i+1,j+1][0]:=Texture[n];
        inc(n);
        Map.Data[i,j][1]:=Texture[n];
        Map.Data[i,j+1][1]:=Texture[n];
        Map.Data[i+1,j][1]:=Texture[n];
        Map.Data[i+1,j+1][1]:=Texture[n];
        inc(n);
        Map.Data[i,j][2]:=Texture[n];
        Map.Data[i,j+1][2]:=Texture[n];
        Map.Data[i+1,j][2]:=Texture[n];
        Map.Data[i+1,j+1][2]:=Texture[n];
        inc(n);

        if FInfo.Bpp=32 then
          begin
            Map.Data[i,j][3]:=Texture[n];
            Map.Data[i,j+1][3]:=Texture[n];
            Map.Data[i+1,j][3]:=Texture[n];
            Map.Data[i+1,j+1][3]:=Texture[n];
            inc(n);
          end;
        inc(j,2);
      end;
      inc(i,2);
      j:=0;
      end;
    end;
  end;

 result:=true;
end;
nXs вне форума Ответить с цитированием
Старый 26.11.2011, 20:54   #10
nXs
Форумчанин
 
Регистрация: 26.02.2010
Сообщений: 126
По умолчанию

И код в котором появляется NAN
Код:
function TLEForm.CalcNormal(P: TPoint3f): TVector3f;
var
n,d:TVector3f;
s,m:integer;
begin
n:=vector3f(0,0,0);

if (P.x<MSize-2) and(P.z<MSize-2) then
begin
s:=GetintegerVBOValue(trunc(P.z)+1,Trunc(P.x));
m:=GetintegerVBOValue(trunc(P.z),Trunc(P.x)+1);
d:=nMath.CalcNormal(Vertexes[s].Vertex,P,Vertexes[m].Vertex,true);
n:=VectorSumm(n,d);
end;

if (P.x>0) and(P.z>0) then
begin
s:=GetintegerVBOValue(trunc(P.z)-1,Trunc(P.x));
m:=GetintegerVBOValue(trunc(P.z),Trunc(P.x)-1);
d:=nMath.CalcNormal(Vertexes[s].Vertex,P,Vertexes[m].Vertex,true);
n:=VectorSumm(n,d);
end;

if (P.x>0) and (P.z<MSize-2) then
begin
s:=GetintegerVBOValue(trunc(P.z)-1,Trunc(P.x));
m:=GetintegerVBOValue(trunc(P.z),Trunc(P.x)+1);
d:=nMath.CalcNormal(Vertexes[s].Vertex,P,Vertexes[m].Vertex,true); <== здесь d=(NAN,-NAN,NAN)
n:=VectorSumm(n,d);
end;


if (P.x<MSize-2) and (P.z>0) then
begin
s:=GetintegerVBOValue(trunc(P.z)+1,Trunc(P.x));
m:=GetintegerVBOValue(trunc(P.z),Trunc(P.x)-1);
d:=nMath.CalcNormal(Vertexes[s].Vertex,P,Vertexes[m].Vertex,true);
n:=VectorSumm(n,d);
end;

result:=VectorNormalize(n);

end;


function VectorCrossProduct(V1,V2:TVector3f):TVector3f;
begin
 result.x:=v1.y*v2.z-v2.y*v1.z;
 result.y:=v1.z*v2.x-v2.z*v1.x;
 result.z:=v1.x*v2.y-v2.x*v1.y;
end;

function CalcNormal(t1,t2,t3:TPoint3f;normalized:boolean):TVector3f;
var
 v1,v2:TVector3f;
begin
 v1.x:=t1.x-t2.x;
 v1.y:=t1.y-t2.y;
 v1.z:=t1.z-t2.z;
 v2.x:=t2.x-t3.x;
 v2.y:=t2.y-t3.y;
 v2.z:=t2.z-t3.z;
 if normalized then
 result:=VectorNormalize(VectorCrossProduct(v1,v2)) else
 result:=VectorCrossProduct(v1,v2);
end;

function VectorNormalize(V:TVector3f):TVector3f;
var
 IR:GLfloat;
begin
 IR:=1/sqrt(v.x*v.x+v.y*v.y+v.z*v.z);
 result.x:=V.x*IR;
 result.y:=V.y*IR;
 result.z:=V.z*IR;
end;
Я знаю что чужой код понять сложно, тем более тот который так написан, но все же, с такой проблемой сталкиваюсь впервые, и при этом раньше работало же нормально, и ничего в нем не изменялось. помогите, плс.
nXs вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Проверка на NaN (С/С++) Паскалька^^ Помощь студентам 1 26.03.2011 23:11
Что обозначает NaN? WitaliG Помощь студентам 6 22.11.2010 17:50
результат выдает -Nan- Тонущий коржик Помощь студентам 2 25.11.2009 23:28
Выдаёт NAN DM_bite Помощь студентам 2 26.08.2008 20:52
NaN in Math Sibedir Общие вопросы Delphi 15 04.03.2008 06:58