मैं javafx में एक रूबिक्स क्यूब बनाने की कोशिश कर रहा था, जो एक बहुत खराब मॉडल के साथ समाप्त हुआ जैसा कि इसमें दिया गया है छवि। मैं इसके लिए अपने स्रोत को कोड के लिए दे रहा हूं, जहां मैंने आयतों को बनाने और {3 डी में तब्दील करने के लिए RectangleBuilder वर्ग का उपयोग किया है। ग्राफिक्स को ठीक करने के लिए मैंने TriangleMesh वर्ग के आयतों का निर्माण करने की कोशिश की थी और उनमें सामग्री जोड़ने के बाद, उन्हें फिर से उसी खराब ग्राफिक्स में समाप्त करने के लिए 3 डी में तब्दील कर दिया। ऐसा क्यों होता है और इससे कैसे छुटकारा पाया जाए?

import javafx.scene.transform.Rotate;
import javafx.scene.PerspectiveCamera;
import javafx.scene.transform.Translate;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.SceneAntialiasing;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.scene.shape.RectangleBuilder;
import javafx.scene.transform.Rotate;
import javafx.util.Duration;


    public class NewFXMain1 extends Application {


    public class Cube extends Group {
    final Rotate rx = new Rotate(0,Rotate.X_AXIS);
    final Rotate ry = new Rotate(0,Rotate.Y_AXIS);
    final Rotate rz = new Rotate(0,Rotate.Z_AXIS);
    public Cube(double size, Color back,Color bottom,Color right,Color left,Color top,Color front, double shade) {
        getTransforms().addAll(rz, ry, rx);
        getChildren().addAll(
            RectangleBuilder.create() // back face
                .width(size).height(size)
                .fill(back.deriveColor(0.0, 1.0, (1 - 0.5*shade), 1.0))
                .translateX(-0.5*size)
                .translateY(-0.5*size)
                .translateZ(0.5*size)
                    .smooth(true)
                    .stroke(Color.BLACK)
                .build(),
            RectangleBuilder.create() // bottom face
                .width(size).height(size)
                .fill(bottom.deriveColor(0.0, 1.0, (1 - 0.4*shade), 1.0))
                .translateX(-0.5*size)
                .translateY(0)
                .rotationAxis(Rotate.X_AXIS)
                .rotate(90)
                    .smooth(true)
                    .stroke(Color.BLACK)
                .build(),
            RectangleBuilder.create() // right face
                .width(size).height(size)
                .fill(right.deriveColor(0.0, 1.0, (1 - 0.3*shade), 1.0))
                .translateX(-1*size)
                .translateY(-0.5*size)
                .rotationAxis(Rotate.Y_AXIS)
                .rotate(90)
                    .smooth(true)
                    .stroke(Color.BLACK)
                .build(),
            RectangleBuilder.create() // left face
                .width(size).height(size)
                .fill(left.deriveColor(0.0, 1.0, (1 - 0.2*shade), 1.0))
                .translateX(0)
                .translateY(-0.5*size)
                .rotationAxis(Rotate.Y_AXIS)
                .rotate(90)
                    .smooth(true)
                    .stroke(Color.BLACK)
                .build(),
            RectangleBuilder.create() // top face
                .width(size).height(size)
                .fill(top.deriveColor(0.0, 1.0, (1 - 0.1*shade), 1.0))
                .translateX(-0.5*size)
                .translateY(-1*size)
                .rotationAxis(Rotate.X_AXIS)
                .rotate(90)
                    .smooth(true)
                    .stroke(Color.BLACK)
                .build(),
            RectangleBuilder.create() // front face
                .width(size).height(size)
                .fill(front)
                .translateX(-0.5*size)
                .translateY(-0.5*size)
                .translateZ(-0.5*size)
                    .smooth(true)
                    .stroke(Color.BLACK)
                .build()
        );
    }
    }



    PerspectiveCamera camera = new PerspectiveCamera(true);
    @Override public void start(Stage primaryStage) throws Exception {

    Group root = new Group();
    Scene scene=new Scene(root,600,600,true);

    camera.setNearClip(0.00001);
    camera.setFarClip(10000000.0);

    camera.getTransforms().addAll (
            new Rotate(0, Rotate.Y_AXIS),
            new Rotate(0, Rotate.X_AXIS),

            new Translate(0, 0, -1000));
    scene.setCamera(camera);
    Cube c1 = new Cube(50,Color.BLUE.darker(),Color.BLUE.darker(),Color.ORANGE.darker(),Color.BLUE.darker(),Color.BLUE.darker(),Color.RED.darker(),1);
     c1.setTranslateX(100);

    Cube c2 = new Cube(50,Color.GREEN.darker(),Color.GREEN.darker(),Color.GREEN.darker(),Color.YELLOW.darker(),Color.BLUE.darker(),Color.RED.darker(),1);
    c2.setTranslateX(50);

    Cube c3 = new Cube(50,Color.CYAN.brighter(),Color.GREEN.darker(),Color.GREEN.darker(),Color.YELLOW.darker(),Color.BLUE.darker(),Color.RED.darker(),1);
    c3.setTranslateX(50);
    c3.setTranslateZ(50);

    Cube c4 = new Cube(50,Color.CYAN.brighter(),Color.GREEN.darker(),Color.ORANGE.darker(),Color.YELLOW.darker(),Color.BLUE.darker(),Color.RED.darker(),1);
    c4.setTranslateX(100);
    c4.setTranslateZ(50);

    Cube c5 = new Cube(50,Color.BLUE.darker(),Color.GREEN.darker(),Color.ORANGE.darker(),Color.BLUE.darker(),Color.BLUE.darker(),Color.RED.darker(),1);
     c5.setTranslateX(100);
     c5.setTranslateY(50);

    Cube c6 = new Cube(50,Color.GREEN.darker(),Color.GREEN.darker(),Color.GREEN.darker(),Color.YELLOW.darker(),Color.BLUE.darker(),Color.RED.darker(),1);
    c6.setTranslateX(50);
    c6.setTranslateY(50);

    Cube c7 = new Cube(50,Color.CYAN.brighter(),Color.GREEN.darker(),Color.GREEN.darker(),Color.YELLOW.darker(),Color.BLUE.darker(),Color.RED.darker(),1);
    c7.setTranslateX(50);
    c7.setTranslateZ(50);
    c7.setTranslateY(50);

    Cube c8 = new Cube(50,Color.CYAN.brighter(),Color.GREEN.darker(),Color.ORANGE.darker(),Color.YELLOW.darker(),Color.BLUE.darker(),Color.RED.darker(),1);
    c8.setTranslateX(100);
    c8.setTranslateZ(50);
    c8.setTranslateY(50);
    handleMouse(scene,root);
    Group k=new Group(c1,c2,c3,c4,c5,c6,c7,c8);
    k.setTranslateZ(70);
    root.getChildren().addAll(k);
    primaryStage.setScene(scene);
    primaryStage.show();
    }
    public static void main(String[] args) { launch(args); }
    private static final double CONTROL_MULTIPLIER = 0.1;   
    private static final double SHIFT_MULTIPLIER = 10.0;   
    private static final double MOUSE_SPEED = 0.1;    
  private static final double ROTATION_SPEED = 2.0; 
  double mousePosX,mousePosY,mouseOldX,mouseOldY,mouseDeltaX,mouseDeltaY;
  private void handleMouse(Scene scene, final Node root) {


    scene.setOnMousePressed(new EventHandler<MouseEvent>() {
        @Override public void handle(MouseEvent me) {
             mousePosX = me.getSceneX();
             mousePosY = me.getSceneY();
             mouseOldX = me.getSceneX();
             mouseOldY = me.getSceneY();
        }
    });
    scene.setOnMouseDragged(new EventHandler<MouseEvent>() {
        @Override public void handle(MouseEvent me) {
            mouseOldX = mousePosX;
            mouseOldY = mousePosY;
            mousePosX = me.getSceneX();
            mousePosY = me.getSceneY();
            mouseDeltaX = (mousePosX - mouseOldX); 
            mouseDeltaY = (mousePosY - mouseOldY);

           double modifier = 1.0;

           if (me.isControlDown()) {
                modifier = CONTROL_MULTIPLIER;
            } 
            if (me.isShiftDown()) {
                modifier = SHIFT_MULTIPLIER;
            }     
            if (me.isPrimaryButtonDown()) {
                camera.setRotationAxis(Rotate.Y_AXIS);camera.setRotate(camera.getRotate() -
                   mouseDeltaX*modifier*ROTATION_SPEED);  // 
               camera.setRotationAxis(Rotate.X_AXIS);camera.setRotate(camera.getRotate() +
                   mouseDeltaY*modifier*ROTATION_SPEED);  // -

            }
            else if (me.isSecondaryButtonDown()) {
                double z = camera.getTranslateZ();
                double newZ = z + mouseDeltaX*MOUSE_SPEED*modifier;
                camera.setTranslateZ(newZ);
            }

       }
   }); // setOnMouseDragged
 } //handleMouse
}
1
Debarun Mukherjee 30 नवम्बर 2015, 18:19

2 जवाब

सबसे बढ़िया उत्तर

संपादित करें:

मूल रूप से यहां दी गई कलाकृतियों को प्रस्तुत करने का कारण गलत था, और प्रस्तावित समाधान उचित नहीं हो सकता है *। विवरण संशोधन इतिहास में पाया जा सकता है। वास्तविक समाधान कहीं अधिक सरल है। किसी भी असुविधा के लिए क्षमा याचना।

कलाकृतियों के प्रतिपादन का कारण यह है कि आपके कैमरा क्लिप प्लेन बहुत दूर हैं। आप सेट कर रहे हैं

camera.setNearClip(0.00001);
camera.setFarClip(10000000.0);

जो कि समझदारी से एक सामान्य Z- बफर में प्रतिनिधित्व किया जा सकता है से परे है। इन लाइनों को बदलना

camera.setNearClip(0.1);
camera.setFarClip(10000.0);

प्रतिपादन त्रुटियों को ठीक करेगा।


* मूल समाधान ने कई Mesh इंस्टेंस से बक्से को मॉडल करने का सुझाव दिया। इसका लाभ यह है कि यह मानदंडों को परिभाषित करने की अनुमति देता है और इस प्रकार "यथार्थवादी" 3 डी प्रभाव को प्राप्त करने के लिए, लेकिन इसमें थोड़ा और प्रयास शामिल है। "वास्तविक 3D" समाधान के लिए संशोधन इतिहास देखें।

3
Community 23 मई 2017, 10:27

जबकि @ मार्को 13 एक महान और वैध उत्तर है, यदि आप एक मॉडल का आयात नहीं करना चाहते हैं, जैसा कि @jewelsea उल्लेख है, प्रत्येक घन के लिए एक एकल जाल बनाने का एक तरीका भी है और चेहरे को रंग दें रूबिक क्यूब के लिए आवश्यक है।

इसे net

Cube Net

यदि आप इस छवि को Box पर लागू करते हैं:

Box cube = new Box();
PhongMaterial material = new PhongMaterial();
material.setDiffuseMap(new Image(getClass().getResource("cubeNet.png").toExternalForm()));
cube.setMaterial(material);

आपको छह चेहरों के लिए एक ही छवि दोहराई जाएगी।

तो आप बनावट निर्देशांक को ठीक से मैप करने के लिए अपना खुद का बॉक्स बना सकते हैं, या CuboidMesh का उपयोग कर सकते हैं > पुस्तकालय।

CuboidMesh cube = new CuboidMesh();
cube.setTextureModeImage(getClass().getResource("cubeNet.png").toExternalForm());

Cuboid texture

यह पोस्ट आपको दिखाता है एक ही जाल के विभिन्न चेहरे कैसे रंगे जा सकते हैं।

संपादित करें

यह देखते हुए कि 27 में से किसी एक के लिए, एक अलग छवि प्रदान की जानी चाहिए, एक बेहतर दृष्टिकोण बस इस तरह की छवि का उपयोग कर रहा है:

Palette

और फिर तदनुसार बनावट सूचकांकों को संशोधित करें, जैसा कि इस उत्तर में बताया गया है।

मूल रूप से, प्रत्येक रंग के लिए:

public static final int RED     = 0;
public static final int GREEN   = 1;
public static final int BLUE    = 2;
public static final int YELLOW  = 3;
public static final int ORANGE  = 4;
public static final int WHITE   = 5;
public static final int GRAY    = 6;

इसका सामान्यीकृत x बनावट समन्वय होगा:

public static final float X_RED     = 0.5f / 7f;
public static final float X_GREEN   = 1.5f / 7f;
public static final float X_BLUE    = 2.5f / 7f;
public static final float X_YELLOW  = 3.5f / 7f;
public static final float X_ORANGE  = 4.5f / 7f;
public static final float X_WHITE   = 5.5f / 7f;
public static final float X_GRAY    = 6.5f / 7f;

तो एक बॉक्स बनाने के लिए TriangleMesh का उपयोग करें:

private TriangleMesh createCube(int[] face) {
    TriangleMesh m = new TriangleMesh();
    m.getPoints().addAll(
     0.5f,  0.5f,  0.5f,
     0.5f, -0.5f,  0.5f,
     0.5f,  0.5f, -0.5f,
     0.5f, -0.5f, -0.5f,
    -0.5f,  0.5f,  0.5f,
    -0.5f, -0.5f,  0.5f,
    -0.5f,  0.5f, -0.5f,
    -0.5f, -0.5f, -0.5f
    );
    m.getTexCoords().addAll(
     X_RED, 0.5f, 
     X_GREEN, 0.5f,
     X_BLUE, 0.5f, 
     X_YELLOW, 0.5f, 
     X_ORANGE, 0.5f,  
     X_WHITE, 0.5f,
     X_GRAY, 0.5f
    );

अंत में, हमें केवल चेहरों को जोड़ने की आवश्यकता है: कोने और बनावट सूचकांकों की सूची। आइए रुबिक के क्यूब पर चेहरों के सामान्य अंकन के आधार पर सूचकांकों की एक सरणी बनाएं: F - R - U - B - L - D:

    m.getFaces().addAll(
     2, face[0], 3, face[0], 6, face[0],      // F      
     3, face[0], 7, face[0], 6, face[0],  

     0, face[1], 1, face[1], 2, face[1],      // R     
     2, face[1], 1, face[1], 3, face[1],         

     1, face[2], 5, face[2], 3, face[2],      // U   
     5, face[2], 7, face[2], 3, face[2],

     0, face[3], 4, face[3], 1, face[3],      // B      
     4, face[3], 5, face[3], 1, face[3],       

     4, face[4], 6, face[4], 5, face[4],      // L      
     6, face[4], 7, face[4], 5, face[4],    

     0, face[5], 2, face[5], 4, face[5],      // D      
     2, face[5], 6, face[5], 4, face[5]         
    );
    return m;
}

अब एक घन और रंगों के पैटर्न के आधार पर, क्यूब और इसकी 27 क्यूबियाँ बनाना बहुत सरल है।

यह कोड

int[] p = new int[]{BLUE, GRAY, GRAY, GRAY, ORANGE, WHITE};
MeshView meshP = new MeshView();
meshP.setMesh(createCube(p));
PhongMaterial mat = new PhongMaterial();
mat.setDiffuseMap(new Image(getClass().getResourceAsStream("palette.png")));
meshP.setMaterial(mat);

फ्रंट-राइट-अप स्थिति के लिए क्यूबाई बनाएंगे।

27 पदों को परिभाषित करते हुए, यह रुबिक का घन होगा:

Rubik's cube

इसे बनाने के लिए आवश्यक कोड यहां पाया जा सकता है।

1
Community 23 मई 2017, 12:15