CW arc with JavaFX arcTo() or similar function - javafx
Is there a easy way to paint an cw arc with JavaFX arcTo() or similar function?
gc.setFill(Color.LIGHTGRAY);
gc.fillRect(0, 0, 200, 200);
gc.beginPath();
gc.moveTo(20,20);
// CCW arc
gc.arcTo(lastPos[0], lastPos[1], newPos[0], newPos[1], Math.sqrt(offset[0]*offset[0]+offset[1]*offset[1]));
gcGCodeVis.stroke();
gcGCodeVis.closePath();
I tried with following code, but it didn't work correct:
// CW arc
gc.moveTo(newPos[0], newPos[1]);
gc.arcTo(newPos[0]+offset[0], newPos[1]+offset[1], lastPos[0], lastPos[1], Math.sqrt(offset[0]*offset[0]+offset[1]*offset[1]));
gc.moveTo(newPos[0], newPos[1]);
Related
Problem with adding multiple triangle meshes to a scene in javafx
I hope someone can help me with this problem. I am using javafx and triangle mesh to construct a sphere-like object out of triangles (like a football). The different tiles of the shape are distinguished by color but I want to add lines between the tiles. Like in this football: The provided 2D lines of javafx bring terrible performance in the 3D space. Therefore I found the FXyzLib that provides a PolyLine3D. This is actually just another triangle mesh that creates a line in a 3D space. With this I can create 3D lines. But if I want to add them to my original triangle mesh everything else turns black. It is also the other way around. I experimented with the provided example of the Libary found here. It creats a fancy 3D line but when I tried to add a simple red colored sphere to the scene the sphere was just black like this: . I am no expert in this and new to javafx and couldn't find the problem in the code of the PolyLine3D. It shouldn't be a problem to add mutliple triangle mesh to a scene. Are there some light or camera effects I am not aware of? EDIT: I solved the problem. The ambient light used in the Polyline3D caused the problem. If you add light for your other objects it should be fine.
While there is nothing wrong about adding multiple triangle meshes to a scene, there is a more straightforward approach when you want to create a mesh like one from the football picture, so you can have the effect of highlighting some edges but not all the triangles from the mesh. It can be done with a PolygonMesh that takes any valid close polygon as face. This implementation already exists, in the 3DViewer project, which is open source and can be found here. There is a PolygonMeshView control that can render a PolygonMesh. Note that if you use those two classes only in your project, you'll have to skip the subdivision mesh for now. This answer already uses a quadrilateral mesh for a rendering a Box without the diagonal edges of a triangle mesh. Under the hood, the Polygon mesh uses a triangle mesh, and internally converts the polygons you provide to triangles. Truncated Icosahedron Mesh So we can do something similar to generate the mesh of a truncated icosahedron, which is the name of the geometric figure that we can use to generate a simplified football model. It has 12 regular pentagonal faces, 20 regular hexagonal faces and 60 vertices. We need the 3D coordinates of those vertices, the 2D coordinates of the textures, and the indices of vertices and textures for each of the 32 faces. I've used the free online sandbox WolframCloud resource to retrieve those values. For instance, you can run: Flatten[PolyhedronData["TruncatedIcosahedron","VertexCoordinates"]//N] to get the list of vertex coordinates: Out[1]= {-0.16246,-2.11803,1.27598,-0.16246,2.11803,...} and, you can get the faces: PolyhedronData["TruncatedIcosahedron","FaceIndices"] Out[2]= {{53,11,24,23,9},{51,39,40,52,30},...} Finally, you need the textures coordinates and indices, and that can be retrieved through the Net of the icosahedron: PolyhedronData["TruncatedIcosahedron","Net"] PolyhedronData["TruncatedIcosahedron","NetCoordinates"] In this case, you get the 2D coordinates of the 32 faces. Given that we want to have the same texture for all the pentagons and the same for all hexagons, I've dome some manipulation of those coordinates to come up with this texture image: with only 9 vertices, and their coordinates (in the JavaFX coordinate system). This method contains the required information to create the mesh: private PolygonMesh getTruncatedIcosahedron() { float[] points = new float[]{ -0.16246f,-2.11803f,1.27598f, -0.16246f,2.11803f,1.27598f, 0.16246f,-2.11803f,-1.27598f, 0.16246f,2.11803f,-1.27598f, -0.262866f,-0.809017f,-2.32744f, -0.262866f,-2.42705f,-0.425325f, -0.262866f,0.809017f,-2.32744f, -0.262866f,2.42705f,-0.425325f, 0.262866f,-0.809017f,2.32744f, 0.262866f,-2.42705f,0.425325f, 0.262866f,0.809017f,2.32744f, 0.262866f,2.42705f,0.425325f, 0.688191f,-0.5f,-2.32744f, 0.688191f,0.5f,-2.32744f, 1.21392f,-2.11803f,0.425325f, 1.21392f,2.11803f,0.425325f, -2.06457f,-0.5f,1.27598f, -2.06457f,0.5f,1.27598f, -1.37638f,-1.f,1.80171f, -1.37638f,1.f,1.80171f, -1.37638f,-1.61803f,-1.27598f, -1.37638f,1.61803f,-1.27598f, -0.688191f,-0.5f,2.32744f, -0.688191f,0.5f,2.32744f, 1.37638f,-1.f,-1.80171f, 1.37638f,1.f,-1.80171f, 1.37638f,-1.61803f,1.27598f, 1.37638f,1.61803f,1.27598f, -1.7013f,0.f,-1.80171f, 1.7013f,0.f,1.80171f, -1.21392f,-2.11803f,-0.425325f, -1.21392f,2.11803f,-0.425325f, -1.96417f,-0.809017f,-1.27598f, -1.96417f,0.809017f,-1.27598f, 2.06457f,-0.5f,-1.27598f, 2.06457f,0.5f,-1.27598f, 2.22703f,-1.f,-0.425325f, 2.22703f,1.f,-0.425325f, 2.38949f,-0.5f,0.425325f, 2.38949f,0.5f,0.425325f, -1.11352f,-1.80902f,1.27598f, -1.11352f,1.80902f,1.27598f, 1.11352f,-1.80902f,-1.27598f, 1.11352f,1.80902f,-1.27598f, -2.38949f,-0.5f,-0.425325f, -2.38949f,0.5f,-0.425325f, -1.63925f,-1.80902f,0.425325f, -1.63925f,1.80902f,0.425325f, 1.63925f,-1.80902f,-0.425325f, 1.63925f,1.80902f,-0.425325f, 1.96417f,-0.809017f,1.27598f, 1.96417f,0.809017f,1.27598f, 0.850651f,0.f,2.32744f, -2.22703f,-1.f,0.425325f, -2.22703f,1.f,0.425325f, -0.850651f,0.f,-2.32744f, -0.525731f,-1.61803f,-1.80171f, -0.525731f,1.61803f,-1.80171f, 0.525731f,-1.61803f,1.80171f, 0.525731f,1.61803f,1.80171f}; float[] texCoords = new float[]{0.904508f,0.820298f, 0.75f,0.529535f, 0.25f,0.529535f, 0.0954915f,0.820298f, 0.5f,1f, 1f,0.264767f, 0.75f,0f, 0.25f,0f, 0f,0.264767f}; int faces[][] = new int[][]{{52,0,10,1,23,2,22,3,8,4}, {50,0,38,1,39,2,51,3,29,4}, {59,0,27,1,15,2,11,3,1,4}, {19,0,41,1,47,2,54,3,17,4}, {18,0,16,1,53,2,46,3,40,4}, {0,0,9,1,14,2,26,3,58,4}, {35,0,25,1,43,2,49,3,37,4}, {3,0,57,1,21,2,31,3,7,4}, {33,0,28,1,32,2,44,3,45,4}, {20,0,56,1,2,2,5,3,30,4}, {36,0,48,1,42,2,24,3,34,4}, {12,0,4,1,55,2,6,3,13,4}, {8,1,58,5,26,6,50,7,29,8,52,2}, {52,1,29,5,51,6,27,7,59,8,10,2}, {10,1,59,5,1,6,41,7,19,8,23,2}, {23,1,19,5,17,6,16,7,18,8,22,2}, {22,1,18,5,40,6,0,7,58,8,8,2}, {12,1,24,5,42,6,2,7,56,8,4,2}, {4,1,56,5,20,6,32,7,28,8,55,2}, {55,1,28,5,33,6,21,7,57,8,6,2}, {6,1,57,5,3,6,43,7,25,8,13,2}, {13,1,25,5,35,6,34,7,24,8,12,2}, {39,1,37,5,49,6,15,7,27,8,51,2}, {15,1,49,5,43,6,3,7,7,8,11,2}, {11,1,7,5,31,6,47,7,41,8,1,2}, {47,1,31,5,21,6,33,7,45,8,54,2}, {54,1,45,5,44,6,53,7,16,8,17,2}, {53,1,44,5,32,6,20,7,30,8,46,2}, {46,1,30,5,5,6,9,7,0,8,40,2}, {9,1,5,5,2,6,42,7,48,8,14,2}, {14,1,48,5,36,6,38,7,50,8,26,2}, {38,1,36,5,34,6,35,7,37,8,39,2}}; int[] smooth = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32 }; PolygonMesh mesh = new PolygonMesh(points, texCoords, faces); mesh.getFaceSmoothingGroups().addAll(smooth); return mesh; } Now you can easily add it to an scene: private double mouseOldX, mouseOldY = 0; private final Rotate rotateX = new Rotate(0, Rotate.X_AXIS); private final Rotate rotateY = new Rotate(0, Rotate.Y_AXIS); #Override public void start(Stage primaryStage) { PolygonMeshView meshView = new PolygonMeshView(getTruncatedIcosahedron()); final PhongMaterial phongMaterial = new PhongMaterial(); meshView.setDrawMode(DrawMode.LINE); meshView.setMaterial(phongMaterial); final Group group = new Group(meshView); group.getTransforms().add(new Scale(50, 50, 50)); Scene scene = new Scene(group, 500, 300, true, SceneAntialiasing.BALANCED); scene.setOnMousePressed(event -> { mouseOldX = event.getSceneX(); mouseOldY = event.getSceneY(); }); scene.setOnMouseDragged(event -> { rotateX.setAngle(rotateX.getAngle() - (event.getSceneY() - mouseOldY)); rotateY.setAngle(rotateY.getAngle() + (event.getSceneX() - mouseOldX)); mouseOldX = event.getSceneX(); mouseOldY = event.getSceneY(); }); PerspectiveCamera camera = new PerspectiveCamera(false); camera.setNearClip(0.1); camera.setFarClip(1000.0); camera.getTransforms().addAll(rotateX, rotateY, new Translate(-250, -150, 0)); scene.setCamera(camera); primaryStage.setTitle("JavaFX 3D - Truncated Icosahedron"); primaryStage.setScene(scene); primaryStage.show(); } Will give you the wireframe: And if you add the image of the texture, you will get your football: phongMaterial.setDiffuseMap(new Image(getClass().getResourceAsStream("net3.png"))); meshView.setDrawMode(DrawMode.FILL); Now it's up to you to manipulate to your convenience this information, and modify this mesh into the one you are looking for.
QOpenGLFrameBufferObject for 3D graphics
I am currently working on creating openGL buffers in Qt for some 3D models (cuboids of various sizes depicting buildings). I've tried to look into some examples, but I've only found some for 2D. I tried using the same for 3D, but at best I end up with blank images when I convert my buffers to images to check. I reached the max success (at least an image is being created) using: https://dangelog.wordpress.com/2013/02/10/using-fbos-instead-of-pbuffers-in-qt-5-2/ My current code is something like: QOpenGLFramebufferObject* SBuildingEditorUtils::getFboForBuilding(Building bd) { glPushMatrix(); QSurfaceFormat format; format.setMajorVersion(4); format.setMinorVersion(3); QWindow window; window.setSurfaceType(QWindow::OpenGLSurface); window.setFormat(format); window.create(); QOpenGLContext context; context.setFormat(format); if (!context.create()) qFatal("Cannot create the requested OpenGL context!"); context.makeCurrent(&window); // TODO: fbo size = building size QOpenGLFramebufferObjectFormat fboFormat; fboFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); //fboFormat.setAttachment(QOpenGLFramebufferObject::Depth); auto fbo = new QOpenGLFramebufferObject(1500, 1500, fboFormat); auto res = glGetError(); auto bindRet = fbo->bind(); glEnable(GL_DEPTH_TEST); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrtho(0, 1500, 0, 1500, 0, 1500); glMatrixMode(GL_MODELVIEW); glBegin(GL_POLYGON); glVertex3d(500, 500, 500); glVertex3d(500, 1000, 1000); glVertex3d(1000, 1000, 1000); glVertex3d(1000, 500, 500); glEnd(); glDisable(GL_DEPTH_TEST); fbo->toImage().save("uniqueName.png"); fbo->release(); glPopMatrix(); return fbo; } Here I've been using the image "uniqueName.png" to text my output. As you can guess most of the code here just for testing. Also, this code is part of a larger code base. Any advice of what I might be missing. While I have some experience with Qt, I lack any formal education / training in openGL. Any help would be appreciated. I wish to know how to get the code to work. Thanks.
JavaxFX set NodeOrientation for the RotateTransition [duplicate]
in my javafx application, i have an imageView for which I have created an Rotate trasition, everything works fine , but the rotation direction is in counterclockwise of watch, i want to make it in opposite direction . this is My code : RotateTransition rt = new RotateTransition(Duration.millis(3000), myImageView); rt.setByAngle(360); rt.setCycleCount(1); rt.setAutoReverse(false); rt.play() ;
It seems to be undocumented, but setting a negative angle results in a counter-clockwise rotation: rt.setByAngle(-360);
QGL, opengl - all values of zaxis outside of 1;-1 get clipped
All figures outside of z-axis: (1;-1) range get clipped. Here is some code: void MainWindow::initializeGL() { glDepthRange(-2,2); glEnable(GL_TEXTURE_2D); glDisable(GL_COLOR_MATERIAL); glEnable(GL_BLEND); glEnable(GL_POLYGON_SMOOTH); //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glClearColor(1, 1, 0, 0); glDisable(GL_DEPTH_TEST); // Enables Depth Testing glDepthFunc(GL_LESS); // The Type Of Depth Test To Do glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); } void MainWindow::paintGL(){ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); // glEnable(GL_TEXTURE_2D); // glBindTexture(GL_TEXTURE_2D,texture); // glTexSubImage2D(GL_TEXTURE_2D, 0, 0,0 , image.width(), image.height(), 0, 0, image.bits() ); //glMatrixMode(GL_MODELVIEW); //glEnable(GL_DEPTH_TEST); glTranslated(0.0, 0.0, 1.9); qglColor(Qt::black); glBegin(GL_TRIANGLES); glVertex3d(-0.1,0.1,1); glVertex3d(-0.1,-0.1,-1); glVertex3d(0.1,-0.1,0); glEnd(); } Any idea why does it happen?
This is actually completely normal behavior. When you use identity modelview and projection matrices, your coordinates are in clip-space. The default W value for a 3D vertex in OpenGL is 1.0 (vertices are always 4D), and clip-space -> NDC works by dividing each component of a vertex by its W component and then clipping anything with a coordinate outside the range [-1,1]. I think what is confusing you is the glDepthRange (...) call. That does not affect clipping. Depth range is part of the viewport transformation, which happens after clipping.
Qt/OpenGL - draw a 2D "scale line" on top of a 3D scene [duplicate]
This question already has answers here: Opengl: 2d HUD over 3D (3 answers) Closed 6 years ago. I have a subclass "GLWidget" of QGLWidget where I render a 3D scene. I can do rotations and zoom on it. I call with a QTimer the following function : void GLWidget::processCurrent() { draw(); printStats(); glFlush(); swapBuffers(); } and the main OpenGL render function "draw()" is : void GLWidget::draw() { if (isDisplayFirst) { isDisplayFirst = false; glViewport(0, 0, w_width, w_height); glMatrixMode(GL_PROJECTION); // Select The Projection Matrix glLoadIdentity(); // Reset The Projection Matrix glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix glLoadIdentity(); // Reset The Modelview Matrixi gluPerspective(45.0f, (float)w_width / w_height, g_nearPlane, g_farPlane); gluLookAt (0.0, 0.0, 3.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); glScalef(0.03f, 0.03f, 0.03f); } rotateScene(); glClearColor(0.0 ,0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_POINT_SPRITE); glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE); glEnable(GL_VERTEX_PROGRAM_POINT_SIZE_NV); glEnable(GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE); GLuint vbo_disk = 0; glBindBuffer(GL_ARRAY_BUFFER, vbo_disk); glVertexPointer(4, GL_DOUBLE, 4*sizeof(double), Galaxy->pos); glEnableClientState(GL_VERTEX_ARRAY); glColor4f(1.0f, 1.0f, 1.0f, 0.2f); glDrawArrays(GL_POINTS, 0, Galaxy->getNumParticles_disk()); glBindBuffer(GL_ARRAY_BUFFER, 0); glDisableClientState(GL_VERTEX_ARRAY); glDisable(GL_BLEND); glDisable(GL_POINT_SPRITE); } I have already rendered 2D text (statistics) on this GLWidget with "printStats()" function. I would like now to draw a "2D scale line" on this 3D scene. I succeed in draw this line by doing into printStats(): glDisable(GL_TEXTURE_2D); glColor3f(1.0f, 1.0f, 1.0f); glLineWidth(3.0f); glBegin(GL_LINES); glVertex2d(5, 40); glVertex2d(20, 40); glEnd(); glEnable(GL_TEXTURE_2D); but my problem is that when I do rotations or zoom, this line moves with the 3D scene. What is the way to lock this 2D line while being able to do operations on the 3D object ? I want to avoid to use "overpainting" with overriding paintEvent. I also try to use glPush/Pop Matrix but there are conflicts between 2D and 3D. Could you give me some advice to get it ?
You are trying to implement HUD functionality, in principle what you need to to draw your 3D scene normaly, then backup all the OpenGL states that you want to reuse, and set up a new projection matrix with gluOrtho2D or glOrtho. Additionally you want to turn off the depth check. After the call to the ortho function you will most likely draw in screen scale, so you will have to calculate the size of your line accordingly. Once you are done with the hud, you can pop the changes off the stack so you can draw again. There are a couple of questions on stackoverflow that deal with drawing an OpenGl HUD OpenGl 2D HUD over 3D OpenGl 2d HUD in 3D Application and a pretty decent discussion on the gamedev forum http://www.gamedev.net/topic/388298-opengl-hud/