never posted a question before though plenty of lurking, thanks for all the advice you've already unwittingly supplied! Couldn't seem to find any previous answers to help with this. I'm a scientist who's only picked up programming on the fly so tend to be a bodger, hopefully the question makes sense.
How do I set up an java.awt.geom.Area object for a set of triangles (for which I have the coordinates of the corners)?
The problem I’m trying to solve is that I have a mesh of triangles over which I'm drawing a mesh of rectangles and I’m trying to find for each rectangle which triangle or triangles it lies within. The java.awt.geom.Area class has an intersect method which given sufficient looping would seem to solve it - my problem is constructing the areas.
I can create the square mesh as areas in the following (possibly inefficient) manner
Rectangle2D.Double[] squareMesh = new Rectangle2D.Double[totalCells];
int k = 0;
for(int i=0; i < cellsY; i++) {
for(int j=0; j < cellsX; j++) {
squareMesh[k]= new Rectangle2D.Double(cellsXCoords[j],cellsYCoords[i],resolution,resolution);
k++;
}
}
Area[] squareMeshAreas = new Area[totalCells];
for(int i=0; i < totalCells; i++) {
squareMeshAreas[i] = new Area(squareMesh[i]);
}
For the triangles I have the coordinates of the corners for each. The java.awt.Polygon looked hopeful but won't work as it only takes integer coordinates. What is the best way to set up Areas for these triangles?
If there are better ways of solving the problem without using Area class then suggestions are also welcome.
Related
I am developing an application that uses a map. I want to show a polygon with a "hole", in Java Android. I searched, but unfortunately, I could not find a solution. I think my problem is that I can not set the correct fillColor. Can someone help me?
My result:
I want the hole's color to be transparent.
My code:
List<ArrayList<LatLng>> multiLatLon;
...
//draw polygon hole
for(int i=0; i<multiLatLon.size(); i++){
poly = new PolygonOptions();
for (int j=0; j<multiLatLon.get(i).size(); j++){
mop.position(multiLatLon.get(i).get(j));
poly.add(multiLatLon.get(i).get(j));
Marker m = mMap.addMarker(mop);
}
poly.fillColor(R.color.colorOcher);
Polygon polygon = mMap.addPolygon(poly);
}
Let me know if you need more info.
Solution:
...
poly = new PolygonOptions ();
poly.fillColor (ColorUtils.setAlphaComponent (Color.BLUE, 128));
for (int i = 0; i <multiLatLon.size (); i ++) {
if (i == 0) {
poly.addAll (multiLatLon.get (i));
} else {
poly.addHole (multiLatLon.get (i));
}
}
mMap.addPolygon(poly);
In my case, I know that the first point array (multiLatLon.get (i)) defines the polygon geometry; while the others are the polygon holes.
Note: I used addAll to delete one for loop
I think the solution you're looking for is the addHole function in the PolygonOptions class.
Give that function your points (as Iterable<LatLng>) you want to have a hole and you should be good to go.
I don't know exactly where the values of your hole are in your code, but basically, you just call that function like this :
poly = new PolygonOptions();
// set the polygon's attributes
//...
//Iterable<LatLng> hole = //whatever contains the hole
poly.addHole(hole);
My question does not refer to what operators I need to use to manipulate matrices, but rather what is actually being sought by doing this procedure.
I have, for example, an image in matrix form on which I need to perform several operations (this filter is one of them). After converting said image to grayscale, I need to apply the following filter
float[][] smoothKernel = {
{0.1f,0.1f,0.1f},
{0.1f,0.2f,0.1f},
{0.1f,0.1f,0.1f}
};
on it.
The assignment file gives this example , so I assumed that when asked to "smooth" the image, I had to replace every individual pixel with an average of its neighbors (while also making sure special cases such as corners or side were handled properly).
The basic idea is this:
public static float[][] filter(float[][] gray, float[][] kernel) {
// gray is the image matrix, and kernel is the array I specifed above
float current = 0.0f;
float around = 0.0f;
float[][] smooth = new float[gray.length][gray[0].length];
for (int col = 0; col < gray.length; col++) {
for (int row = 0; row < gray[0].length; row++) {
//first two for loops are used to do this procedure on every single pixel
//the next two call upon the respective pixels around the one in question
for (int i = -1; i < 2; i++) {
for (int j = -1; j < 2; j++) {
around = at(gray, i + col, j + row); //This calls a method which checks for the
//pixels around the one being modified
current += around * kernel[i+1][j+1];
//after the application of the filter these are then added to the new value
}
}
smooth[col][row] = current;
current = 0.0f;
//The new value is now set into the smooth matrix
}
}
return smooth;
}
My dilemma lies in if I have to create this new array float[][] smooth; so as to avoid overriding the values of the original (the image outputted is all white in this case...). From the end product in the example I linked above I just cannot understand what is going on.
What is the correct way of applying the filter? Is this a universal method or does it vary for different filters?
Thank you for taking the time to clarify this.
EDIT: I have found the two errors which I detailed in the comments below, implemented back into the code, everything is working fine now.
I have also been able to verify that some of the values in the example are calculated incorrectly (thus contributing to my confusion), so I will be sure to point it out in my next class.
Question has been solved by ulterior methods, I am however not deleting it in hopes other people can benefit from it. The original code can be found in the edits.
A more advanced colleague of mine helped me to note that I was missing two things: one was the issue with resetting the current variable after computing the "smoothed" variables in the new array (resulting in a white image because this value would get increasingly larger thus surpassing the binary color limit, so it was set to the max). The second issue was that I was continuously iterating on the same pixel, which caused the whole image to have the same color (I was iterating the new array). So I added these specifications in, and all works fine since.
I am having a problem with a basic code which displays some animated images in a 150x150 grid on the screen. (Note: Yes i know the images go off the edge of the screen but in the end i was planning to scale the images as required to fit the screen). However the program only runs at 2 FPS causing the animation to sometimes not work. My loop is currently as follows (in Java):
for (int i = 0; i < 22; i++) {
for (int j = 0; j < 11; j++) {
g2d.drawImage(getImage(texture_Ocean,l),i*64,j*64,i*64+64,j*64+64,0,0,64,64,this);
}
}
And getImage:
public Image getImage(Image i, Long l) {
BufferedImage b = (BufferedImage) i;
int w = b.getWidth();
if (b.getHeight() % w == 0) {
int frames = b.getHeight()/w;
int frame = Math.round((l%1000)/(1000/frames));
System.out.println(frame);
return b.getSubimage(0,(int) (w*frame) ,w, w);
} else {
return texture_error;
}
}
My question is how can i make my program more efficient/run quicker? I know there has to be a way to do it as you see games such as prison architect and rimworld with words that are 300x300 and have hundreads of entities. And games such as TF2 which display thousands of polygons in 3D space. How?
The problem is that you are using the CPU (and through inefficient memory access methods as well) to do a job that the GPU is much better for.
You need to look at using something like a 2d graphics or games library or similar to get the sort of performance you are looking for.
The thing is, when developing games, you should care a lot with optimization. You can't simply call a paint method if you don't need it, and hope everything will be alright.
Besides that, you should try to look for a library dedicated to graphics (like OpenGL), since they can handle the optimization easily with the hardware.
I currently have a program that draws overlapping rectangles and was wondering if there is an easy way to determine which shape is on the top (most visible). This has me stumped as there is no z axis to use like in when dealing in 3D.
I have tried looping through the rectangles and using the .contains method but it returns all rectangles under a specific point and not the highest level one.
I have also searched around but perhaps I'm using the wrong keywords?
Normally when people do painting code they do something like:
List rectangles = ....
for (int i = 0; i < rectangles.size(); i++)
//paint the rectangle
So if you want to search for a Point to determine what Rectanle it is in then you should use:
for (int i = rectangles.size() - 1; i >= 0; i--)
{
if (rectangles.get(i).contains(yourPoint))
{
// do something
break;
}
}
Starting from the end will give you the last rectangle painted which means it is on top of all aother rectangles.
Background:
I have two 2d arrays. Each index within each 2d array represents a tile which is drawn on a square canvas suitable for 8 x 8 tiles.
The first 2d array represents the ground tiles and is looped and drawn on the canvas using the following code:
//Draw the map from the land 2d array
map = new Canvas(mainFrame, 20, 260, 281, 281);
for(int i=0; i < world.length; i++){
for(int j=0; j < world[i].length; j++){
for(int x=0; x < 280; x=x+35){
for(int y=0; y < 280; y=y+35){
Point p = new Point(x,y);
map.add(new RectangleObject(p,35,35,Colour.green));
}
}
}
}
This creates a grid of green tiles 8 x 8 across as intended.
The second 2d array represents the position on the ground. This 2d array has everyone of its indexes as null apart from one which is comprised of a Person class.
Problem
I am unsure of how I can draw the position on the grid. I was thinking of a similar loop, so it draws over the previous 2d array another set of 64 tiles. Only this time they are all transparent but the one tile which isn't null. In other words, the tile where Person is located.
I wanted to use a search throughout the loop using a comparative if statement along the lines of
if(!(world[] == null)){
map.add(new RectangleObject(p,35,35,Colour.red));}
However my knowledge is limited and I am confused on how to implement it.
Do not use a second Array at all. Simply create a RectangleObject named, for example, currentPosition or activeTile or personPosition.
You, however, do not really need to store the Point in the RectangleObject. Either use a 2D RectangleObject array for that (so that you can use the indexes to access them) and exclude the Point information in the RectangleObject,
or
create a List of RectangleObjects and add the Point information - but do not increment by 35, but rather by 1. When you're drawing the tiles, you can still (by knowing the index) figure out where to put the tile (e.g. indexX*tileWidth, indexY*tileHeight).
(It's not quite clear from what you've written what world and map are used for. Please explain so I can give a better answer)