1 Востаннє редагувалося FakiNyan (17.01.2015 19:47:02)

Тема: Дивний float з буковкою E ніяк не обробляється [ВИРІШЕНО]

Хай. Суть задачі була така - зайти в Unity3D, експортувати дані карти висот в файлик, потім зайти в Java-проект, завантажити ці дані, і по ним побудувати таку ж карту, яка була в Unity3D.
Простіше кажучи - перенести зображення 3D об'єкту, котрий задається картою висот з одної проги в іншу.
Ну от я напісюлькав такий код в Java. З комунтарями!

    private void Import(String path) throws Exception
    {
        byte[] bytes = Files.readAllBytes(Paths.get(path)); // зчитую дані з файла
        int resolution = (int)Math.sqrt(bytes.length/4); // дані були типу float[,] , тому таким чином я дізнаюсь розмірність матриці
        float[] floats=new float[resolution*resolution]; // завантажую всі ці дані в одномірний масив, тому що не існує ніяких матриць, є тільки масиви!!1
        ByteBuffer.wrap(bytes).asFloatBuffer().get(floats); // перетворюю масив байтиків в масив float'ів
        float step = 100/(resolution-1.0f); // визначаю "проміжність" між вертексами, в даному коді не використовується

        for(int i =0; i<20; i++) // тестую з 20*20 квадратиками, в фінальній версії тут буде resolution-1
        {
            for(int j =0; j<20; j++)
            {
                vectors.add(new Vector3f(i,(float)Math.ceil(floats[i*resolution+j]),j)); // визначаю 4 вертекси майбутнього кваду
                vectors.add(new Vector3f(i+1,(float)Math.ceil(floats[(i+1)*resolution+j]),j));
                vectors.add(new Vector3f(i+1,(float)Math.ceil(floats[(i+1)*resolution+(j+1)]),j+1));
                vectors.add(new Vector3f(i,(float)Math.ceil(floats[i*resolution+(j+1)]),j+1));

                System.out.println((float)Math.ceil(floats[i*resolution+j])); // висвітлюю значення висот для перевірки
                System.out.println((float)Math.ceil(floats[(i+1)*resolution+j]));
                System.out.println((float)Math.ceil(floats[(i+1)*resolution+(j+1)]));
                System.out.println((float)Math.ceil(floats[i*resolution+(j+1)]));
            }
        }
    }

Квади будуються от так

Прихований текст

http://не-дійсний-домен/eE6KL/ae5eec98ba.png

Біда в тому, що в масиві з висотами знаходяться от такі дані (я їх спробував округлити, аби обійти проблеми кривих float'ів, але ті криві флоати мають імунітет до округлення)

Прихований текст
-0.0
-0.0
-2.0
-2.0
-0.0
-0.0
-2.0
-3.7533254E19
-0.0
-0.0
-3.7533254E19
-3.7533254E19
-0.0
-0.0
-3.7533254E19
-3.7533254E19
-0.0
-0.0
-3.7533254E19
-3.7533254E19
-0.0
-0.0
-3.7533254E19
-3.7533254E19
3.7497226E19
3.7497226E19
-3.7533254E19
-2.0
3.7497226E19
3.0
-0.0
-2.0
3.0
3.0
-2.0
-2.0
3.0
3.0
-2.0
-3.7533254E19
-0.0
-0.0
-3.7533254E19
1.0
-0.0
-0.0
1.0
1.0
-0.0
-0.0
1.0
1.0
-3.7533254E19
-3.7533254E19
1.0
1.0
-3.7533254E19
-3.7533254E19
1.0
1.0
-3.7533254E19
-3.7533254E19
1.0
1.0
-3.7533254E19
-3.7533254E19
1.0
3.0
-3.7533254E19
-3.7533254E19
3.0
3.0
-3.7533254E19
-3.7533254E19
3.0
3.0
-3.7533254E19
-3.7533254E19
3.0
3.7857514E19
-2.0
-2.0
3.7857514E19
3.7857514E19
-2.0
-2.0
3.7857514E19
3.7857514E19
-3.7533254E19
-3.7533254E19
3.7857514E19
1.0
-3.7533254E19
-3.7533254E19
1.0
-3.7533254E19
-3.7533254E19
-3.7533254E19
-3.7533254E19
-3.7533254E19
-3.7533254E19
-3.7533254E19
-3.7533254E19
-3.7533254E19
-3.7533254E19
-3.7533254E19
-3.7533254E19
-3.7533254E19
-2.0

Як бачите, деякі float'и округлились, а от ті з експонентою - ні.
Як то вирішити? Округлювати дані вже при записі, чи як?
p.s. от сітка, котра будується, якщо замінити висоти на константу
код виглядає так

 for(int i =0; i<20; i++) // тестую з 20*20 квадратиками, в фінальній версії тут буде resolution-1
        {
            for(int j =0; j<20; j++)
            {
                vectors.add(new Vector3f(i,0,j)); // визначаю 4 вертекси майбутнього кваду
                vectors.add(new Vector3f(i+1,0,j));
                vectors.add(new Vector3f(i+1,0,j+1));
                vectors.add(new Vector3f(i,0,j+1));

                System.out.println((float)Math.ceil(floats[i*resolution+j])); // висвітлюю значення висот для перевірки
                System.out.println((float)Math.ceil(floats[(i+1)*resolution+j]));
                System.out.println((float)Math.ceil(floats[(i+1)*resolution+(j+1)]));
                System.out.println((float)Math.ceil(floats[i*resolution+(j+1)]));
            }
        }

а сітка так

Прихований текст

http://не-дійсний-домен/eE7hn/23ef449344.png

тобто проблема саме в висотах

2

Re: Дивний float з буковкою E ніяк не обробляється [ВИРІШЕНО]

я тут був прочитав, що таке експонента, і зрозумів, що та карта ніфіга не вірна, тому що в мене немає таких великих значень

3

Re: Дивний float з буковкою E ніяк не обробляється [ВИРІШЕНО]

допомогло

ByteBuffer.wrap(bytes).order(ByteOrder.nativeOrder()).asFloatBuffer().get(floats);

правда дані про ті висоти в якомусь незрозумілому форматі, і мені довелось множити кожну висоту на 2000, і тоді все щось більш-менш схоже на правду почалось вимальовуватись

Прихований текст

http://не-дійсний-домен/eEbMj/118ffb0de0.png

4

Re: Дивний float з буковкою E ніяк не обробляється [ВИРІШЕНО]

Я б не став стверджувати, що вони не округлились. Щоб це побачити, треба вивести 20+ знаків в форматі без експоненти.

5

Re: Дивний float з буковкою E ніяк не обробляється [ВИРІШЕНО]

quez написав:

Я б не став стверджувати, що вони не округлились. Щоб це побачити, треба вивести 20+ знаків в форматі без експоненти.

ну я то вже зрозумів, читайте усі комунтарії, бдлск

6

Re: Дивний float з буковкою E ніяк не обробляється [ВИРІШЕНО]

Про округлення нічого не написано, не обманюйте.

7

Re: Дивний float з буковкою E ніяк не обробляється [ВИРІШЕНО]

quez написав:

Про округлення нічого не написано, не обманюйте.

про експоненту написано