Применить градиент к объекту сферы с помощью JavaFX

Я работаю в JavaFX для класса и пытаюсь применить градиент к сфере, но (очевидно) не могу понять, как это сделать. Я застрял, потому что знаю, что сфера - это объект, и поэтому у нее должен быть материал, но (что касается цветов) PhongMaterial принимает только один цвет, и поэтому он не будет использовать градиент, потому что градиент - это диапазон цветов. Итак, в основном я пытаюсь сделать следующее:

    Sphere sphere = new Sphere(50);
    RadialGradient rg = new RadialGradient(0, 0, 0, 0, 5, true, CycleMethod.REPEAT, /*arbitrary/irrelevant color Stop objects*/));
    PhongMaterial pm = new PhongMaterial();
    pm.setDiffuseMap(pm);
    sphere.setMaterial(asdf);

Теперь очевидно, что этот код не работает, но я думаю, что это идея/поток того, что я пытаюсь сделать.


person TheRandomSpectator    schedule 21.06.2018    source источник


Ответы (1)


Вы правы в одном: PhongMaterial принимает Color за диффузный цвет, а это не позволяет использовать Gradient. Для этого он должен принять Paint, но это не так.

Поэтому приходится искать разные альтернативы.

Рассеянная карта

Если вы отметите PhongMaterial, вы можете установить диффузная карта с изображением. Это означает, что вы можете использовать существующее изображение с некоторым градиентом и применить его к сфере.

Что-то вроде этого:

Sphere sphere = new Sphere(100);
PhongMaterial material = new PhongMaterial();
material.setDiffuseMap(new Image("http://westciv.com/images/wdblogs/radialgradients/simpleclorstops.png"));
sphere.setMaterial(material);

даст следующий результат:

Динамическая диффузная карта

Очевидно, что это имеет тот недостаток, что зависит от статического изображения. Что делать, если вы хотите изменить это динамически?

Вы можете сделать это, если создадите свой радиальный градиент, визуализируете его на вторичной сцене и сделаете снимок. Этот снимок возвращает WritableImage, который вы можете использовать непосредственно как диффузную карту.

Что-то вроде этого:

Scene aux = new Scene(new StackPane(), 100, 100, 
        new RadialGradient(0, 0, 0.5, 0.5, 1, true, CycleMethod.REPEAT, 
                new Stop(0, Color.GREEN), new Stop(0.4, Color.YELLOW), 
                new Stop(0.6, Color.BLUE), new Stop(0.7, Color.RED)));
WritableImage snapshot = aux.snapshot(null);

Sphere sphere = new Sphere(100);
PhongMaterial material = new PhongMaterial();
material.setDiffuseMap(snapshot);
sphere.setMaterial(material);

Теперь у вас будет:

Карта плотности

Существует еще один вариант использования математической функции для создания карты плотности, и цвета будут заданы сопоставлением с этой функцией.

Для этого вы не можете использовать встроенный Sphere, но вы должны либо создать свой собственный TriangleMesh и поиграть с координатами текстуры, либо вы можете просто использовать FXyz, JavaFX 3D с открытым исходным кодом библиотека с рядом различных примитивов и опций текстуры.

В этом случае вы можете получить библиотеку из Maven Central (org.fxyz3d:fxyz3d:0.3.0), использовать элемент управления SegmentedSphereMesh, а затем выбрать режим текстуры `Vertices3D:

SegmentedSphereMesh sphere = new SegmentedSphereMesh(100);
sphere.setTextureModeVertices3D(1530, p -> p.z);

Обратите внимание, что функция в этом случае просто основана на координате z, но, очевидно, вы можете изменить ее по мере необходимости.

Проверьте библиотеку (есть сэмплер), чтобы изучить другие варианты.

person José Pereda    schedule 21.06.2018