I want to make the node go further instead of starting from initial coordinates and going a certain distance can anyone help me?
public void sky(Node node, double xDest, double yDest) {
TranslateTransition tTrans = new TranslateTransition(
Duration.millis(4000), node);
tTrans.setFromX(0);
tTrans.setFromY(0);
tTrans.setToY(yDest);
tTrans.setToX(xDest);
tTrans.setRate(2);
tTrans.setInterpolator(Interpolator.LINEAR);
tTrans.play();
}
The method above moves a node with xDest and yDest.
xDest = x coordinate and yDest = y coordinate
If the initial coordinates are 100, 100 and xDest = 50 and yDest = 50 then when i press the button the node will go to 150, 150 but if i press the button again the animation shows the node starting from 100, 100 and going to 150, 150. I want it to go to 200, 200 at second mouse click, any ideas please ?
Use the byX and byY properties instead of the toX and toY properties:
public void sky(Node node, double deltaX, double deltaY) {
TranslateTransition tTrans = new TranslateTransition(
Duration.millis(4000), node);
tTrans.setFromX(node.getTranslateX());
tTrans.setFromY(node.getTranslateY());
tTrans.setByY(deltaY);
tTrans.setByX(deltaX);
tTrans.setRate(2);
tTrans.setInterpolator(Interpolator.LINEAR);
tTrans.play();
}
Now each time you call this with deltaX=50 and deltaY=50 it will translate it by an additional 50 pixels along both axes.
Related
Is it possible to draw a shape with open ends?
E.g.: Let's say I want to draw a tree, which roots are open. Is there a elegant way to let the ends open, without overdrawing the already drawed lines?
I could overdraw it with shapes, which are exactly as big as my openings and have the color of the background, but I don't think that is the elegant way and I don't find any option to let them open. Perhaps I'm just blind and I could make strokePolygon(...) in which not all points are linked, but I think that's neither the way to go.
Let's have a simple shape:
[ceate Scene and Stage, etc]
Canvas sc = new Canvas(x, y);
GraphicsContext gcCs = cs.getGraphicsContext2D();
gcCs.setStroke(Color.BLACK);
double counter = 0.0;
[calculate points, instantiate arrays, etc]
for (int i = 0; i < arrayX.length; i++)
{
arrayX = shapeMidX + Math.cos(Math.toRadiants(counter * Math.PI)) * shapeSizeX / 2);
arrayY = shapeMidY + Math.sin(Math.toRadiants(counter * Math.PI)) * shapeSizeY / 2);
}
gcCs.strokePolygon(arrayX, arrayY, arrayX.length);
[making other things]
stackPane.getChildren().add(sc);
I know that I could use .strokeOval(), but I wanted to have a example that is near of my own code.
I like to draw my shapes from the center.
P.S.: I wrote the for() { } out of my head, it could be that there's something wrong. I've got no Internet at home at the moment, so my answers could be taking a lot of time.
Thank you in advance.
You could draw individual lines using strokeLine and store the current position in variables allowing you to draw any combination of lines.
You could also construct a path instead which allows you to use moveTo instead of lineTo to "skip" a segment. This way you don't need to keep track of the previous position for continuous lines.
The following example draws every other line of a square this way:
#Override
public void start(Stage primaryStage) {
Canvas canvas = new Canvas(400, 400);
GraphicsContext gc = canvas.getGraphicsContext2D();
gc.moveTo(100, 100);
gc.lineTo(100, 300);
gc.moveTo(300, 300);
gc.lineTo(300, 100);
// gc.moveTo(100, 100);
gc.stroke();
Scene scene = new Scene(new StackPane(canvas));
primaryStage.setScene(scene);
primaryStage.show();
}
I am currently working with gmap.net to create a certain radius with a polygon. I currently have made a polygon for the radius but now I come to the problem that I want to create multipule markers but only show the markers who are inside the polygon. Is this possible?
_polygonOverlay = new GMapOverlay("destination");
_gMap.Overlays.Add(_polygonOverlay);
private void CreateCircle(PointLatLng destination, double radius)
{
List<PointLatLng> radiusPoint = new List<PointLatLng>();
double seg = Math.PI * 2 / 40;
for (int i = 0; i < 40; i++)
{
double theta = seg * i;
double latitude = destination.Lat + Math.Cos(theta) * radius;
double longitude = destination.Lng + Math.Sin(theta) * radius;
PointLatLng cirlePoint = new PointLatLng(latitude, longitude);
radiusPoint.Add(cirlePoint);
}
GMapPolygon radiusCircle = new GMapPolygon(radiusPoint, "radius");
_polygonOverlay.Polygons.Add(radiusCircle);
}
private void CreateMarkers()
{
_polygonOverlay.Markers.Add(new GMarkerGoogle(new PointLatLng(xxx, xxx), GMarkerGoogleType.blue));
_polygonOverlay.Markers.Add(new GMarkerGoogle(new PointLatLng(xxx, xxx), GMarkerGoogleType.blue));
_polygonOverlay.Markers.Add(new GMarkerGoogle(new PointLatLng(xxx, xxx), GMarkerGoogleType.blue));
}
Here is a little sample of the code I have that create a circle (still needs some work on it) and some markers.
Already thanks is advance
Since you are dealing with a circle, you should be able to simply check the distance of your marker from the center of the circle. If the distance is greater than the radius, don't add it to the overlay.
GMap gives you access to the necessary methods to determine this information. Do something like this:
//Assuming p1 is your marker and p2 is your circle center coordinate
double markerDist = GMap.NET.MapProviders.EmptyProvider.Instance.Projection.GetDistance(p1.Position, p2);
if(markerDist <= circleRadius)
{
//Add the marker to the overlay
}
Assume you have a GMapPolygon with some Points, you could just use
bool inside = gMapPolygon.IsInside(point)
to check if the point of a GMarker is inside that GMapPolygon
I am drawing differently sized maps on a pane. Some look decent, others are just presented as a small shape and you have to zoom in to get it to the right size. I want those maps to appear roughly the same size each time I initialize (so I don't have to manually scale each map). I've got Point2D points for the min and max values of x and y of the pane they're drawn on and same goes for the map (which is a Group of polygons). How do I set the distance between, say, the minPoint of Pane and the minPoint of Group? Or am I approaching this the wrong way?
edit:
public void setDistance(Group map, Point2D paneSize, Point2D mapSize){
//um diese distance verschieben, if distance > 10px (scale)
double d = paneSize.distance(mapSize);
double scale = ??
map.setScaleX(scale);
map.setScaleY(scale);
}
That's how I planned on doing it, not sure about that one line though.
To scale the node to the size of the parent node, the difference in the size is not important. What is important is the quotient of the sizes, more precisely the minimum of the quotients of the heights and the widths (assuming you want to fill the parent in one direction completely).
Example:
#Override
public void start(Stage primaryStage) {
Text text = new Text("Hello World!");
Pane root = new Pane();
root.getChildren().add(text);
InvalidationListener listener = o -> {
Bounds rootBounds = root.getLayoutBounds();
Bounds elementBounds = text.getLayoutBounds();
double scale = Math.min(rootBounds.getWidth() / elementBounds.getWidth(),
rootBounds.getHeight() / elementBounds.getHeight());
text.setScaleX(scale);
text.setScaleY(scale);
// center the element
elementBounds = text.getBoundsInParent();
double cx = (elementBounds.getMinX() + elementBounds.getMaxX()) / 2;
double cy = (elementBounds.getMinY() + elementBounds.getMaxY()) / 2;
text.setTranslateX(rootBounds.getWidth() / 2 - cx + text.getTranslateX());
text.setTranslateY(rootBounds.getHeight() / 2 - cy + text.getTranslateY());
};
root.layoutBoundsProperty().addListener(listener);
text.layoutBoundsProperty().addListener(listener);
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}
i am trying to create a kind of metaball, nice curves between two circles.
Something like the image, the lines are drawn straight but can also be more curved. I need them as a vector in Processing. Does anyone can help me?
thanks in advance!
Example in paperjs:
http://paperjs.org/examples/meta-balls/
image:
http://www.smeulders.biz/tmp/metaballs.png
void setup() {
size(500,500);
ellipse(100, 250, 100, 100);
ellipse(350, 250, 200, 200);
}
void draw() {}
With a bit of math (to workout distance between circles) and a bit of pixel manipulation to set pixel colours based on these calculated distances, you can render 2D metaballs and there plenty of examples
For fun however I decided to take a stab at making a very hacky version of the example you shared by simply rendering ellipses into an image, then filtering the image at the end:
PGraphics pg;//a separate layer to render into
int dilateAmt = 3;
PImage grid;//pixels of the grid alone, minus the 'cursor'
void setup(){
size(400,400);
//create a new layer
pg = createGraphics(width,height);
pg.beginDraw();
//draw a di-grid inside
pg.background(255);
pg.noStroke();pg.fill(0);
for(int y = 0 ; y < 5; y++)
for(int x = 0 ; x < 5; x++)
pg.ellipse((y%2==0?40:0)+(x * 80),40+(y * 80), 40, 40);
pg.endDraw();
//grab a snapshot for later re-use
grid = pg.get();
}
void draw(){
pg.beginDraw();
//draw the cached grid (no need to loop and re-render circles)
pg.image(grid,0,0);
//and the cursor into the layer
pg.ellipse(mouseX,mouseY,60,60);
pg.endDraw();
//since PGraphics extends PImage, you can filter, so we dilate
for(int i = 0; i < dilateAmt; i++) pg.filter(DILATE);
//finally render the result
image(pg,0,0);
}
void keyPressed(){
if(keyCode == UP) dilateAmt++;
if(keyCode == DOWN) dilateAmt--;
if(dilateAmt < 1) dilateAmt = 1;
println(dilateAmt);
}
Note that the end result is raster, not vector.
If you want to achieve the exact effect you will need to port your example from JavaScript to Java. The source code is available.
If you like Processing the above example you could use plain javascript using p5.js. You'll find most of the familiar functions from Processing, but also directly use the paper.js library.
I am getting started with JavaFX and basically what I am trying to implement is a Color Picker.
At first, I thought of having a rectangle with a LinearGradient that goes through all primary/secondary colors.
Looks like what I want, but the problem is that I can not get the RGB values at a given coordinate(x,y) in this Node.
I know you can do it through the fill property of any Shape IF it is a Color.
But Is there anyway to get the RGB values of anything inside a LinearGradient/Paint ?
Does this ColorPicker JavaFX example help?
[...]
function colorAtLocation(x:Integer, y:Integer) : Color {
var bimg = iv.image.bufferedImage;
if (x < 0 or x >= bimg.getWidth() or y < 0 or y >= bimg.getHeight()) {
return null;
}
var rgb = bimg.getRGB(x, y);
var r = Bits.bitAnd(Bits.shiftRight(rgb, 16), 0xff);
var g = Bits.bitAnd(Bits.shiftRight(rgb, 8), 0xff);
var b = Bits.bitAnd(Bits.shiftRight(rgb, 0), 0xff);
Color.rgb(r, g, b)
}
function updateSelectedColor(e:MouseEvent) {
var rgb = colorAtLocation(e.x, e.y);
if (rgb != null) {
picker.selectedColor = rgb;
}
}
[...]
The ColorPicker JavaFX example starts with a png image that is loaded to an image that then populates the ImageView.
The question starts with a JavaFX Rectangle containing LinearGradient.
To get the rectangle contents into a buffered image, one can use the java.awt.Robot:
var rectangle = new java.awt.Rectangle(x,y,width,height);
var robot = new java.awt.Robot();
var bufferedImage = robot.createScreenCapture(rectangle);
where rectangle would be describe the coordinates of the JavaFX Rectangle containing the bits of interest.
The robot.createScreenCapture call has the gotcha that to do the screen capture, the screen has to be visible. There should be a better of way to populate the buffered image but I've not yet encountered it.