Generate irregular blob Shape in java - java

I'm trying to generate a random irregular java.awt.Shape blob, something like the examples in the second answer (the one by Paul Gaborit) to this question on tex.stackexchange.com.
If there is a way to start with an Ellipse2D and then modify that similar to how it is done in TeX in that answer, great.
Otherwise, maybe I could do something like this?:
public Shape createShape(int pointCount, double max_deviation, int median_radius,
int[] center)
{
int[][] pathPoints = new int[pointCount][2];
Random rand = new Random();
for (int i=0;i<pointCount;i++)
{
double angle = (2*Math.PI/((double)pointCount))*((double)i);
double temp_deviation = (0.5-rand.nextDouble())*2.0*max_deviation;
double temp_radius = median_radius+temp_deviation;
int x = (int) Math.round(temp_radius*Math.cos(angle));
int y = (int) Math.round(temp_radius*Math.sin(angle));
pathPoints[i] = new int[] {x+center[0],y+center[1]};
}
// somehow make pathPoints into a Shape with smooth curves
return shape;
}
Still, that would only produce a crude initial blob. It would be nice if I could then introduce fined grained random ripples in that random shape.

Related

tile disappearing from rubiks cube with rotation

I'm working on a 2x2 rubik cube, and was having trouble getting one side rotate with my program. The cube is a 2d array of squares. I'm just triying to do a 90 degree counter clockwise turn.
This is what happens
https://imgur.com/a/tlskNKY
I changed the colour so I could see the specific squares and how they changed. I tried changing the order, moving specific pieces at a time to see if the problem was just overlapping pieces (no such luck).
//square class
public class square implements Comparable {
int c;
private Rectangle r;
int xpos, ypos, width, height;
public square(int a, int x, int y) {
c = a;
xpos = x;
ypos = y;
r = new Rectangle(xpos, ypos, 50, 50);
}
//some unused methods
}
//inside the cube class
public class cube{
square[] temp = new square[4]
square[][] sq= new square[6][4]
//two for loops make squares and fills the sq 2d array
//the result is in the imgur link
public void turnVc(){
temp= sq[2];
sq[2][0]=temp[1];
sq[2][1]=temp[3];
sq[2][2]=temp[2];
sq[2][3]=temp[0];
}
}
I expect the output to be the original image turned counter clockwise.
tmp is a pointer that points to the same object that sq[2] pointers. That's why when you change sq[2] content, you change tmp's as well.
i think instead of assign "temp= sq[2];" you should do the following:
temp = new square[4];
for (int i = 0; i < 4; i++) {
temp[i] = sq[2][i];
}
Edit:
i think a little improvement you could do is that you don;t need to save all the sq[2] array, you could only save the fist item. i would do like this (tmp is now a square, not an array):
tmp = sq[2][0];
sq[2][0] = sq[2][1];
sq[2][1] = sq[2][3];
sq[2][3] = sq[2][2];
sq[2][2] = tmp;
If your square class implements Cloneable, you should use clone() method possible, it is also similar to answer of #Nguyen Tan Bao, but shorter
I guess you 're C++ dev, reference in Java is like pointer in C++, you can research more Have fun !

Perlin Noise repeating pattern

My problem that my perlin noise is repeating itself very obviously in very small spaces. Here is an image of what it going on. I know that this does happen after a certain point with all perlin noise, but it seems to be happening almost immediately with mine. I believe that it is caused by my really awful pseudorandom gradient generator, but Im not sure. My code is below.
As a side note, my perlin noise seems to generate very small values, between -.2 and positive .2 and I think this is also caused by my pseudorandom gradient generator.
If anyone has any advice on improving this part of my code, please feel free to tell me. Any ideas would be helpful right now.
Thanks to everyone in advance!
public class Perlin {
int[] p = new int[255];
public Perlin() {
for(int i = 0; i < p.length; i++)
p[i] = i;
shuffle(p);
}
int grads[][] = {
{1,0},{0,1},{-1,0},{0,-1},
{1,1},{-1,1},{1,-1},{-1,-1}
};
public double perlin (double x, double y) {
int unitX = (int)Math.floor(x) & 255; // decide unit square
int unitY = (int)Math.floor(y) & 255; // decide unit square
double relX = x-Math.floor(x); // relative x position
double relY = y-Math.floor(y); // relative y position
// bad pseudorandom gradient -- what i think is causing the problems
int units = unitX+unitY;
int[] gradTL = grads[p[(units)]%(grads.length)];
int[] gradTR = grads[p[(units+1)]%(grads.length)];
int[] gradBL = grads[p[(units+1)]%(grads.length)];
int[] gradBR = grads[p[(units+2)]%(grads.length)];
// distance from edges to point, relative x and y inside the unit square
double[] vecTL = {relX,relY};
double[] vecTR = {relX-1,relY};
double[] vecBL = {relX,relY-1};
double[] vecBR = {relX-1,relY-1};
// dot product
double tl = dot(gradTL,vecTL);
double tr = dot(gradTR,vecTR);
double bl = dot(gradBL,vecBL);
double br = dot(gradBR,vecBR);
// perlins fade curve
double u = fade(relX);
double v = fade(relY);
// lerping the faded values
double x1 = lerp(tl,tr,u);
double y1 = lerp(bl,br,u);
// ditto
return lerp(x1,y1,v);
}
public double dot(int[] grad, double[] dist) {
return (grad[0]*dist[0]) + (grad[1]*dist[1]);
}
public double lerp(double start, double end, double rate){
return start+rate*(end-start);
}
public double fade(double t) {
return t*t*t*(t*(t*6-15)+10);
}
public void shuffle(int[] p) {
Random r = new Random();
for(int i = 0; i < p.length; i++) {
int n = r.nextInt(p.length - i);
// do swap thing
int place = p[i];
p[i] = p[i+n];
p[i+n] = place;
}
}
}
A side note on my gradient generator, I know Ken Perlin used 255 because he was using bits, I just randomly picked it. I dont think it has any effect on the patterns if it is changed.
Your intuition is correct. You calculate:
int units = unitX+unitY;
and then use that as the base of all your gradient table lookups. This guarantees that you get the same values along lines with slope -1, which is exactly what we see assuming (0, 0) is the upper-left corner.
I would suggest using a real hash function to combine your coordinates: xxHash, Murmur3, or even things like CRC32 (which isn't meant to be a hash) would be much better than what you're doing. You could also implement Perlin's original hash function, although it has known issues with anisotropy.

Determine touch/click of 4 Polygons from a Rectangle using libgdx

I'm currently working with libgdx, and am trying to get 4 equal Polygons from a Rectangle:
Rectangle myRect = Rectangle(0, 0, 171, 171);
I am looking to determine the 4 Polygons that represent each side of the Rectangle
This is my first day working with this engine, and I am a bit rusty on my geometry, so I'm looking for any help I can get. Essentialy, I'm going to use these Polygons to determine whether a specified X,Y pair is within them.
Thanks for the help.
You could find the mid point of the rectangle fairly easily, just average the height and width. From there you could manually construct a polygon, jumping from corner to corner to midpoint. You would lose some precision due to rounding, but you can use getX() and getWidth() if you need double precision.
public Polygon[] findTris(Rectangle rectangle){
//Creating a list of the x points of the rectangle, ordered clockwise.
new int[] xpoints = new int[5];
xpoints[0] = rectangle.x;
xpoints[1] = rectangle.x+rectangle.width;
xpoints[2] = rectangle.x+rectangle.width;
xpoints[3] = rectangle.x;
xpoints[4] = rectangle.x;
//Doing the same for y points.
int[] ypoints = new int[5];
ypoints[0] = rectangle.y;
ypoints[1] = rectangle.y;
ypoints[2] = rectangle.y+rectangle.height;
ypoints[3] = rectangle.y+rectangle.height;
ypoints[4] = rectangle.y;
//Finding the midpoint.
int midx = (rectangle.x+rectangle.width)/2;
int midy = (rectangle.y+rectangle.height)/2;
//Creating an array to hold the polygons.
Polygon[] polys = new Polygon[4];
//Creating the polygons.
for(int i = 0; i < 4; i++){
int[] triXPoints = {xpoints[i], xpoints[i+1], midx};
int[] triYPoints = {ypoints[i], ypoints[i+1], midy};
polys[i] = Polygon(xpoints,ypoints,3);
}
return polys;
}
Now that will work fine, but if all you are trying to do is find the mouse position in a square, you can use mouse maps. A mouse map is an image with distinctly different colors in each region that you want to be able to recognize the mouse in. You would store the map as a BufferedImage and whenever you needed to find the region the mouse was in, you can get the color of the buffered image at the appropriate position on the BufferedImage.
Here is the idea:
http://i.stack.imgur.com/iFPsl.png

how to generate random numbers of random colors for canvas.drawColor

I am still new at android development and all the app i've been dealing with so far are not graphical related. Now i am making a app that displays a graph, pie graph to be exact and im making this without any 3rd party libs. This is the tutorial which i followed.
Now the problem is the data which i will be using to construct the graph is dynamic, and so to assign each item with a color for the graph i need to generate a number of random colors for the canvas.drawColor. the number of colors will of course depend on my dynamic data which is determined at run time and the color value also needs to be generated.
Also it would be nice if the colors generated are vibrant colors that stands out.
I've never dealt with canvas, any idea how this can be done? Example code would be much appreciated.
Thanks
It would be quite hard to get different and usefull colors at runtime. The best is not to use so much randomness, but make an array of let's say 20 fixed colors quite distinct and use the X first ones for your data. If you need more, then maybe use real random colors using random RGB values :
Random r = new Random();
Color c = new Color( r.nextInt(255), r.nextInt(255), r.nextInt(255) );
You should take a random float for each color component:
Random rand = new Random();
float r = rand.nextFloat();
float g = rand.nextFloat();
float b = rand.nextFloat();
Since you want vibrant colors, you could use the Color.brighter() method.
Color c = new Color(r, g, b);
c = c.brighter();
Otherwise you could set a threshold, so that the color values have a minimum value (higher is brighter):
float minimumBrightness = 0.6; //higher is more vibrant
float r = rand.nextFloat(1-minimumBrightness) + minimumBrightness; //for each component
This will ensure vibrant colors.
I wouldn't use just completely random colors. You'd get completely different saturations and brightnesses which will look plain ugly.
You could fix a saturation (choose a high value for vibrant colors) and brightness and choose a random hue value, but you would run the risk of getting two consecutive pie-slices with almost the same color.
I would compute a set of spread out hue-values as shown in the answer to this question:
How to dynamically compute a list of colors?
Reposting the answer below
import java.awt.*;
public class TestComponent extends JPanel {
int numCols = 6;
public void paint(Graphics g) {
float h = 0, dh = (float) getHeight() / numCols;
Color[] cols = getDifferentColors(numCols);
for (int i = 0; i < numCols; i++) {
g.setColor(cols[i]);
g.fillRect(0, (int) h, getWidth(), (int) (h += dh));
}
}
public static Color[] getDifferentColors(int n) {
Color[] cols = new Color[n];
for (int i = 0; i < n; i++)
cols[i] = Color.getHSBColor((float) i / n, 1, 1);
return cols;
}
public static void main(String s[]) {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new TestComponent());
f.setSize(400, 400);
f.setVisible(true);
}
}
If you need like more than 30 colors, you could of course change the brightness and perhaps the saturation as well, and have, for instance, 10 dark colors, 10 midtone colors, and 10 bright colors.

How to avoid overlapping polygon

I created a program to draw many polygons automatically everytimes user presses a button. The points of the polygon are generated automatically using the random function. The problem is that, since the points of the polygon were randomly generated, some of the polygon are overlap with other polygon. How can I avoid this, so that every polygon shown without being overlapped?
.....
List<Polygon> triangles = new LinkedList<Polygon>();
Random generator = new Random();
public void paintComponent(Graphics g) {
for(int i = 0; i < 10; i++) {
double xWidth = generator.nextDouble() * 40.0 + 10.0;
double yHeight = generator.nextDouble() * 40.0 + 10.0;
xCoord[0] = generator.nextInt(MAX_WIDTH);
yCoord[0] = generator.nextInt(MAX_HEIGHT);
xCoord[1] = (int) (xCoord[0] - xWidth);
xCoord[2] = (int) (xCoord[1] + (xWidth/2));
yCoord[1] = yCoord[0];
yCoord[2] = (int) (yCoord[1] - yHeight);
triangles.add( new Polygon(xCoord,yCoord, 3));
}
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setStroke(new BasicStroke(1));
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.00f));
g2.setPaint(Color.black);//set the polygon line
for (Polygon triangle : triangles) g2.drawPolygon(triangle);
Polygon[] triArray = triangles.toArray(new Polygon[triangles.size()]);
for (Polygon p:triArray) triangles.remove (p);
}
Check out the game programming wiki on Polygon Collision:
http://gpwiki.org/index.php/Polygon_Collision
You could break your canvas into 10 regions and constrain your polygons each to their own region. To do this, you could use your i value and a %100 (or other suitable magnitude) of your randomly generated value and apply them to your x coordinates and y coordinates as applicable. The result would be a grid of similarly constrained(no larger than the grid cell), but randomly shaped, Polygons.
EDIT:
Taking another look and fooling around a bit, I took the general concept as I described above and made a stab at an implementation:
public void paintComponent(Graphics g) {
int[] xCoord = new int[3];
int[] yCoord = new int[3];
int colCnt = 5;
int rowCnt = 2;
int maxCellWidth = getWidth() / colCnt;
int maxCellHeight = getHeight() / rowCnt;
for (int i = 0; i < (colCnt * rowCnt); i++) {
int xMultiple = i % colCnt;
int yMultiple = i / colCnt;
for (int j = 0; j < 3; j++) {
xCoord[j] = generator.nextInt(maxCellWidth)
+ (maxCellWidth * xMultiple);
yCoord[j] = generator.nextInt(maxCellHeight)
+ (maxCellHeight * yMultiple);
}
triangles.add(new Polygon(xCoord, yCoord, 3));
}
//... the rest of your method
}
As you can see, all of the Polygons have all points randomly generated, as opposed to your method of generating the first point and then making the rest relative to the first. There is a sense of randomness that is lost, however, as the Polygons are laid out in a grid-like pattern.
Create Area objects from your new polygon as well as for all existing polygons.
Subtract the new polygon's area from the existing ones. If the subtract changed the area, the polygons overlap.
Area newArea = new Area(newPolygon);
Area existingArea = new Area(existingPolygon);
Area existingAreaSub = new Area(existingPolygon); existingAreaSub.subtract(newArea);
boolean intersects = existingAreaSub.equals(existingArea);
You could implement a method Polycon.containsPoint( x, y ) and repeat your random generation until this method returns false for all drawn Polygons.
I have achieved this in Android Using Kotlin (See github project) by using JTS see here
Step-1:
Add JTS library to your project
implementation group: 'org.locationtech.jts', name: 'jts-core', version: '1.15.0'
Step-2:
Create JTS polygon objects for both polygon
// create polygons One
var polygoneOneArray: ArrayList<Coordinate> = ArrayList()
for (points in polygonOnePointsList) {
polygoneOneArray.add(Coordinate(points.latitude(), points.longitude()))
}
val polygonOne: org.locationtech.jts.geom.Polygon = GeometryFactory().createPolygon(
polygoneOneArray.toTypedArray()
)
// create polygons Two
var polygoneTwoArray: ArrayList<Coordinate> = ArrayList()
for (points in polygoneTwoPointsList) {
polygoneTwoArray.add(Coordinate(points.latitude(), points.longitude()))
}
val polygonTwo: org.locationtech.jts.geom.Polygon = GeometryFactory().createPolygon(
polygoneTwo.toTypedArray()
)
Step-3:
Get Common Area of both Polygon
val intersection: org.locationtech.jts.geom.Geometry = polygonOne.intersection(polygonTwo)
Step-4:
Remove common Area from polygonTwo
val difference: org.locationtech.jts.geom.Geometry = polygonTwo.difference(intersection)
Step-5:
Merge Both polygonOne and update polygonTwo
val union: org.locationtech.jts.geom.Geometry = mergePolygonList.get(0).polygons.union(difference)
Step-5:
Now pick points from Geometry and draw a final merged Polygon
val array: ArrayList<Coordinate> = union.coordinates.toList() as ArrayList<Coordinate>
val pointList: ArrayList<Point> = ArrayList()
for (item in array) {
pointList.add(Point.fromLngLat(item.y, item.x))
}
var list: ArrayList<List<Point>> = ArrayList<List<Point>>()
list.add(pointList)
style.addSource(
GeoJsonSource(
"source-id${timeStamp}",
Feature.fromGeometry(Polygon.fromLngLats(list))
)
)

Categories