Positioning of 3d boxes in JavaFx - java

I'm a beginner in JavaFx 3d modelling. I'm trying to create a 3d-model of boxes in a room. I have the dimensions of the boxes and the coords from the front-left-bottom corner of every box. I've tried to set the coords with setTranslateX(), but the result isn't correct. Here is the pice of my code where I try to set the coords:
for (int i = 0; i < Main.load.size(); i++) {
Load l=Main.load.get(i);
Box sphere = new Box(l.getLength()*10, l.getWidth()*10, l.getHeight()*10);
sphere.setTranslateX(l.getX()*10);
sphere.setTranslateY(l.getY()*10);
sphere.setTranslateZ(l.getZ()*10);
PhongMaterial m = new PhongMaterial();
m.setDiffuseColor(new Color(Math.random(),Math.random(),Math.random(),1));
m.setSpecularColor(Color.BLACK);
sphere.setMaterial(m);
root.getChildren().add(sphere);
}
I hope someone can help me.
Here is an example:
Sizes:
blue (30,50,50)
pink (10,10,20)
Position:
blue (0,0,0)
pink (30,0,0)
And this is what I get

When you do a translation of a JavaFX 3D object like a Box you need to account half the width of the object along any axis. The default placement for a Box is to be centered at the origin meaning the center of the Box object is at 0,0,0. Your width is 30 * 10 but your translateX converts to 0*10=0. So the right most edge of your blue box will be X=150 (300 / 2.0 = 150). Your Pink Box has a translateX of 10*30=300. The center of the pink box will be translated to 300 which means the left most edge will be at 300 - (width/2.0) = 300 - (50) = 250.

Related

JavaFX Label an Axis in 3D

So I have this scene
The Axes are just JavaFX Boxes that I created to represent the axes.
How would I label the axes? I've tried using JavaFX Label and Text objects but they just display in 2D, but I may be using them wrong. Is there some way to label (e.g. put the numbers 1, 2, 3, 4, 5 along the axes) these axes in 3D?
We've added a Floating Label example to fxyz3d.org... check out the sample:
FloatingLabels.java
To generically manage 2D labels connected to a Point3D you need to do a transform along the following:
Point3D coordinates = node.localToScene(javafx.geometry.Point3D.ZERO);
SubScene oldSubScene = NodeHelper.getSubScene(node);
coordinates = SceneUtils.subSceneToScene(oldSubScene, coordinates);
double x = coordinates.getX();
double y = coordinates.getY();
label.getTransforms().setAll(new Translate(x, y));
There are other details you have to worry about like properly adding to the subscene and clipping but those are included in the example.

Image and Canvas coordinate displacement when drawing

I am drawing lines on Canvas of SurfaceView which is in FrameLayout. I receive image from camera preview, process it, get coordinates of rectangles and raw the lines of it on canvas. I get a displacement of those lines in y axis when drawn, the lower the line is, the bigger displacement occurs (see photos below):
With red line I marked (with Paint program, not the actual app) the approximate position of where the coordinates coordinates of lower line are on bitmap, and the lower green line of rectangle (placed by the actual app, drawn on canvas) along with red line shows, how much coordinates are displaced. The coordinates on top cannot cross the screen, but on the bottom they can- if the rectangle is low enough, lines come below the screen, but on top they do not (they should not do that on either of all 4 sides, because the given coordinates are never out of bitmap).
The drawing function looks like this:
public void DrawAllContours(List<Point[]> rectPoints, int ratio)
{
paint.setColor(Color.GREEN);
paint.setStrokeWidth(2.5f);
canvas = sh.lockCanvas();
canvas.drawColor(0, PorterDuff.Mode.CLEAR);
for (int i = 0; i < rectPoints.size(); i++)
{
for (int j = 0; j < 4; j++)
canvas.drawLine((float)rectPoints.get(i)[j].x*ratio, (float)rectPoints.get(i)[j].y*ratio,
(float)rectPoints.get(i)[(j+1)%4].x*ratio, (float)rectPoints.get(i)[(j+1)%4].y*ratio, paint);
}
sh.unlockCanvasAndPost(canvas);
}
The ratio variable is the difference between the actual preview image size and resized bitmap for processing size (usualy the value is 3). The actual coordinates are as they should be on preview bitmap, but not on Canvas.
How can I overcome this issue and place lines on their exact places?
Thank you in advance.
So I found out, that camera preview size does differ from the canvas size. My preview size was 1920X1080, and canvas 1845X1080 or so, so thats why Y coordinate was displaced. I just found out the difference ratio and drew lines respectively by that ratio. Canvas resolution can be found with Canvas.getWidth(), Canvas.getHeight().

How to center actors in a group with Scene2d and LibGDX?

I'm using LibGDX and Scene2d and I want to create a pop-up that looks like the one shown in the image below.
So far, I created a table and set the background to a semitransparent color. Then I created an image with a white background. This image expands x, so it is centered. Now I want to have a label centered inside the image. To overlay these two actors, I created a group, but I couldn't find out how to center something in a group. How can I do this?
Here is my code:
Table table = new Table();
table.top();
table.setFillParent(true);
table.setBackground(getColoredBackground(color));
labelStyle = new Label.LabelStyle(font, fontColor);
label = new Label(message, labelStyle);
Image image = new Image(whiteBackground);
image.setSize(table.getWidth() - padding, label.getHeight() + extraHeight);
Group group = new Group();
group.setSize(image.getWidth(), image.getHeight());
group.addActor(image);
group.addActor(label);
table.add(group).expandX().padTop(padTop);
The group has it own coordinates system. It means that when you are setting actor position to (0,0) for example and then adding it to group which is actually at (100, 100) position then the object will be at (100, 100) position relative to the stage.
All you need to do is just to set:
label.setPosition( group.getWidth() / 2f - label.getWidth() / 2f, group.getHeight() / 2f - label.getHeight() / 2f );
after setting Group size. Remember that setting actor's position we are defining its left bottom corner position and that's why you need to also subtract the half of label width/height.
Of course you can modify the y position it doesn't have to be centered vertically also

How to compute a rectangle coordinates from one point and its distances to the four edges

I would like to create a Rectangle that has got one side different than the other.
(All lines depicted are meant to be straight lines)
The normal rectangle is generated like new Rectangle(50 /*LocationX*/, 50 */LocationY*/, 50 /*SizeX*/, 100 /*SizeY*/);, and looks like this:
However, I want a constructor like new Rectangle(50 /*LocationX*/, 50 */LocationY*/, 25 /*25 from the centre point for the red line*/, 30 /*30 from the centre point for the blue line*/, 50 /*50 from centre for green line*/, 100 /*100 from centre for yellow line*/);
In other words, I effectively want to keep the shape the same but move the centre point.
How can I do that?
In java, rectangles are defined by upper-left corner coordinates, width and height.
If I understand your question here what describes your rectangle:
pointX, pointY coordinates of a point in the rectangle. Named the point.
distanceToTop distance from the point to the top of the rectangle (green line).
distanceToBottom distance from the point to the bottom of the rectangle (yellow line).
distanceToLeft distance from the point to the left of the rectangle (red line).
distanceToRight distance from the point to the right of the rectangle (blue line).
That given. The upper-left corner of the rectangle has for coordinates:
(pointX - distanceToLeft, pointY - distanceToTop)
And the whole rectangle has for size (width, height):
(distanceToLeft + distanceToRight, distanceToTop + distanceToBottom)
So your instance will be:
Rectangle r = new Rectangle(
pointX - distanceToLeft, // upper-left corner X
pointY - distanceToTop, // upper-left corner Y
distanceToLeft + distanceToRight, // width
distanceToTop + distanceToBottom // height
);

Screen X,Y co-ordinates translated to map Lon/Lat co-ordinates

Good day.
I would like to convert a screen x,y pixel location (the location a user tapped/clicked) to a lon/lat location on a map.
The current screen location is in a bounding box, of which you have the top left most and bottom right most lon/lat values.
When the screen is not rotated it is quite simple to translate the x/y position to the lon,lat values:
Let mapboudingbox[0,1] contain top left most lat/lon
mapboundingbox[2,3] contains bottom right most lat/lon
Then the degrees per pixel width = abs(lon2 - lon1)/ screenWidthInPixels
Then the degrees per pixel height = abs(lat2 - lat1)/ screenHeightInPixels
From this you can then get Lon/Lat as follow:
float longitude = ((touchXInPixels) * degreesPerPixelWidth) + mapBoundingBox[1];
float latitude = ((touchYPixels) * degreesPerPixelHeight) + mapBoundingBox[0];
This is easy enough. The problem that I have is calculating the Lat/Lon values when the screen is rotated, i.e:
From this, you can see that the screen has now been rotated by an angle Ө. -180 < Ө < 180
So let's assume the user clicks/taps on the screen FQKD at point Sx,Sy. How can I get the new lon/lat values where the user clicked, assuming that we have point Z and R in Lat/Lon, as well as the angle Ө, as well as the screen height and width in pixels?
Any and all help will be much appreciated!
I would just modify standard rotation and scale algorithm for 2D. Read a bit here:
2dTransformations.
The easiest way to achieve this is with matrices.
A 3x3 matrix can describe the rotation, translation & scale in 2D space.
Using this matrix you can project your map image on to the screen area. And using the inverse of the matrix, you can take a point in screen space to map space.
Pseudocode: (as you don't care what language)
Build your matrix:
var matrix = Matrix.newIdentity();
matrix.postAppendTranslate(tx, ty);
matrix.postAppendScale(zoom);
matrix.postAppendRotate(rot);
Render map image using that matrix.
To reverse a press:
var inverseMatrix = matrix.inverse();
var point = new float[]{touchPointX, touchPointY, 1};
var transformedPoint = inverseMatrix.multiply(point);
var mapX = transformedPoint[0];
var mapY = transformedPoint[1];

Categories

Resources