Problems with making 2D terrain in OpenGL - java

Some time ago I asked this question about how to make a 2D terrain with opengl vertices. I got a good answer, but when trying it out it didn't draw anything, and I can't figure out what's wrong, or how to fix it.
I have this now :
public class Terrain extends Actor {
Mesh mesh;
private final int LENGTH = 1500; //length of the whole terrain
public Terrain(int res) {
Random r = new Random();
//res (resolution) is the number of height-points
//minimum is 2, which will result in a box (under each height-point there is another vertex)
if (res < 2)
res = 2;
mesh = new Mesh(VertexDataType.VertexArray, true, 2 * res, 50, new VertexAttribute(Usage.Position, 2, "a_position"));
float x = 0f; //current position to put vertices
float med = 100f; //starting y
float y = med;
float slopeWidth = (float) (LENGTH / ((float) (res - 1))); //horizontal distance between 2 heightpoints
// VERTICES
float[] tempVer = new float[2*2*res]; //hold vertices before setting them to the mesh
int offset = 0; //offset to put it in tempVer
for (int i = 0; i<res; i++) {
tempVer[offset+0] = x; tempVer[offset+1] = 0f; // below height
tempVer[offset+2] = x; tempVer[offset+3] = y; // height
//next position:
x += slopeWidth;
y += (r.nextFloat() - 0.5f) * 50;
offset +=4;
}
mesh.setVertices(tempVer);
// INDICES
short[] tempIn = new short[(res-1)*6];
offset = 0;
for (int i = 0; i<res; i+=2) {
tempIn[offset + 0] = (short) (i); // below height
tempIn[offset + 1] = (short) (i + 2); // below next height
tempIn[offset + 2] = (short) (i + 1); // height
tempIn[offset + 3] = (short) (i + 1); // height
tempIn[offset + 4] = (short) (i + 2); // below next height
tempIn[offset + 5] = (short) (i + 3); // next height
offset+=6;
}
}
#Override
public void draw(SpriteBatch batch, float delta) {
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
mesh.render(GL10.GL_TRIANGLES);
}
This is being rendered by Libgdx, which also provides the class Mesh, but this is not really relevant since I believe that works fine. My problems lay by the vertex and indices generation. I don't really know how to debug it either, so could anyone please look at it, and help me to find why nothing is being rendered?

After a full day has passed, and I have tried everything to solve it, it seemed I forgot to actually set the indices to the mesh.
mesh.setIndices(tempIn);
One missing line, hours of pain... i'm an idiot :)

Related

How to make the ends of Cylinder transparent in JavaFX

I'm currently trying to make the ends of a Cylinder completely transparent whilst keeping the sides a Material.
I'm unsure how to achieve this. This thread mentions it but all the links are broken
I think I need to use a clipping plane? Although I don't know where to start with that.
Here's what I'm currently using to just simply set a translucent material!
Cylinder line = new Cylinder(getRadius()/4, height);
lineMaterial = new PhongMaterial();
lineMaterial.setDiffuseColor(new Color(1,1,1,0.5));
lineMaterial.diffuseMapProperty();
line.setMaterial(lineMaterial);
One possible way to get transparency is by using a png as the diffuse image, with some transparent pixels.
While this works, if you apply over a built-in JavaFX Cylinder, you won't get the expected result, because the Cylinder applies the same image to both the vertical tube and the two cap faces. So this won't work for your case.
There could be an option to remove the caps from the cylinder mesh and get just a tube, but unfortunately it doesn't export its triangle mesh.
So far, the best option is to create directly the mesh of a tube, and for that we can reuse the mesh of the Cylinder by checking the open source code at the (new) OpenJDK/JFX GitHub repository.
The following method creates a TriangleMesh of a Tube of height h, radius r, with div divisions (producing 2 * div triangles). It is the exact same code as the one in Cylinder, but without the caps points, texture coordinate and faces arrays.
private static TriangleMesh createMesh(int div, float h, float r) {
final int nPoints = div * 2;
final int tcCount = (div + 1) * 2;
final int faceCount = div * 2;
float textureDelta = 1.f / 256;
float dA = 1.f / div;
h *= .5f;
float points[] = new float[nPoints * 3];
float tPoints[] = new float[tcCount * 2];
int faces[] = new int[faceCount * 6];
int smoothing[] = new int[faceCount];
int pPos = 0, tPos = 0;
for (int i = 0; i < div; ++i) {
double a = dA * i * 2 * Math.PI;
points[pPos + 0] = (float) (Math.sin(a) * r);
points[pPos + 1] = h;
points[pPos + 2] = (float) (Math.cos(a) * r);
tPoints[tPos + 0] = 1 - dA * i;
tPoints[tPos + 1] = 1 - textureDelta;
pPos += 3; tPos += 2;
}
// top edge
tPoints[tPos + 0] = 0;
tPoints[tPos + 1] = 1 - textureDelta;
tPos += 2;
for (int i = 0; i < div; ++i) {
double a = dA * i * 2 * Math.PI;
points[pPos + 0] = (float) (Math.sin(a) * r);
points[pPos + 1] = -h;
points[pPos + 2] = (float) (Math.cos(a) * r);
tPoints[tPos + 0] = 1 - dA * i;
tPoints[tPos + 1] = textureDelta;
pPos += 3; tPos += 2;
}
// bottom edge
tPoints[tPos + 0] = 0;
tPoints[tPos + 1] = textureDelta;
tPos += 2;
int fIndex = 0;
// build body faces
for (int p0 = 0; p0 < div; ++p0) {
int p1 = p0 + 1;
int p2 = p0 + div;
int p3 = p1 + div;
// add p0, p1, p2
faces[fIndex+0] = p0;
faces[fIndex+1] = p0;
faces[fIndex+2] = p2;
faces[fIndex+3] = p2 + 1;
faces[fIndex+4] = p1 == div ? 0 : p1;
faces[fIndex+5] = p1;
fIndex += 6;
// add p3, p2, p1
faces[fIndex+0] = p3 % div == 0 ? p3 - div : p3;
faces[fIndex+1] = p3 + 1;
faces[fIndex+2] = p1 == div ? 0 : p1;
faces[fIndex+3] = p1;
faces[fIndex+4] = p2;
faces[fIndex+5] = p2 + 1;
fIndex += 6;
}
for (int i = 0; i < div * 2; ++i) {
smoothing[i] = 1;
}
TriangleMesh m = new TriangleMesh();
m.getPoints().setAll(points);
m.getTexCoords().setAll(tPoints);
m.getFaces().setAll(faces);
m.getFaceSmoothingGroups().setAll(smoothing);
return m;
}
Now you will need to create a MeshView so you can add it to your scene:
private static MeshView createTube(int div, float h, float r) {
MeshView meshView = new MeshView(createMesh(div, h, r));
// meshView.setDrawMode(DrawMode.LINE);
meshView.setCullFace(CullFace.NONE);
PhongMaterial material = new PhongMaterial(Color.RED);
meshView.setMaterial(material);
return meshView;
}
Create and add one to your scene:
MeshView tube = createTube(64, 5f, 1.6f);
Scene scene = new Scene(new Group(tube), 600, 600, true, SceneAntialiasing.BALANCED);
And you will get your tube:
You can also apply a diffuse image as texture:
material.setDiffuseMap(new Image(getClass.getResourceAsStream("440px-JavaFX_Logo.png")));

Inconsistent results from taking average of two RGB values

Why are those pixel rgb values sometimes equal and sometimes not equal? I am learning image processing. It would be great if someone help me out here.
public class ColorTest1 {
Color p1;
Color p2;
ColorTest1() throws IOException, InterruptedException {
BufferedImage bi = ImageIO.read(new File("d:\\x.jpg"));
for (int y = 0; y < bi.getHeight(); y++) {
for (int x = 0; x < bi.getWidth() - 1; x++) {
p1 = new Color(bi.getRGB(x, y));
p2 = new Color(bi.getRGB(x + 1, y));
int a = (p1.getAlpha() + p2.getAlpha()) / 2;
int r = (p1.getRed() + p2.getRed()) / 2;
int g = (p1.getGreen() + p2.getGreen()) / 2;
int b = (p1.getBlue() + p2.getBlue()) / 2;
int x1 = p1.getRGB();
int x2 = p2.getRGB();
int sum1 = (x1 + x2) / 2;
int sum2 = a * 16777216 + r * 65536 + g * 256 + b;
System.out.println(sum1 == sum2);
}
}
}
public static void main(String... areg) throws IOException, InterruptedException {
new ColorTest1();
}
}
This is the image:
Take two pixels. One is black. The other is nearly black but with a slight bit of red in it, just 1/255. Ignore alpha. r will be (0 + 1) / 2 = 0. g and b will be 0 too. x1 will be 0. x2 will be 65536, right? So sum1 will be 65536 / 2 = 32768. sum2 obviously will be 0.
Whenever the sum of either red or green of the two colours is odd, the int division will set the high bit of the next colour in RGB, leading to an unexpected result.

Wave generation with the "Hugo Elias" algorithm please! Java

I appear to have hit a wall in my most recent project involving wave/ripple generation over an image. I made one that works with basic colors on a grid that works perfectly; heck, I even added shades to the colors depending on the height of the wave.
However, my overall goal was to make this effect work over an image like you would see here. I was following an algorithm that people are calling the Hugo Elias method (though idk if he truly came up with the design). His tutorial can be found here!
When following that tutorial I found his pseudo code challenging to follow. I mean the concept for the most part makes sense until I hit the height map portion over an image. The problem being the x and y offsets throw an ArrayIndexOutOfBoundsException due to him adding the offset to the corresponding x or y. If the wave is too big (i.e. in my case 512) it throws an error; yet, if it is too small you can't see it.
Any ideas or fixes to my attempted implementation of his algorithm?
So I can't really make a compile-able version that is small and shows the issue, but I will give the three methods I'm using in the algorithm. Also keep in mind that the buffer1 and buffer2 are the height maps for the wave (current and previous) and imgArray is a bufferedImage represented by a int[img.getWidth() * img.getHeight()] full of ARGB values.
Anyways here you go:
public class WaveRippleAlgorithmOnImage extends JPanel implements Runnable, MouseListener, MouseMotionListener
{
private int[] buffer1;
private int[] buffer2;
private int[] imgArray;
private int[] movedImgArray;
private static double dampening = 0.96;
private BufferedImage img;
public WaveRippleAlgorithmOnImage(BufferedImage img)
{
this.img = img;
imgArray = new int[img.getHeight()*img.getWidth()];
movedImgArray = new int[img.getHeight()*img.getWidth()];
imgArray = img.getRGB(0, 0,
img.getWidth(), img.getHeight(),
null, 0, img.getWidth());
//OLD CODE
/*for(int y = 0; y < img.getHeight(); y++)
{
for(int x = 0; x < img.getWidth(); x++)
{
imgArray[y][x] = temp[0 + (y-0)*img.getWidth() + (x-0)];
}
}*/
buffer1 = new int[img.getHeight()*img.getWidth()];
buffer2 = new int[img.getHeight()*img.getWidth()];
buffer1[buffer1.length/2] = (img.getWidth() <= img.getHeight() ? img.getWidth() / 3 : img.getHeight() / 3);
//buffer1[25][25] = 10;
back = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_ARGB);
this.addMouseListener(this);
this.addMouseMotionListener(this);
}
//<editor-fold defaultstate="collapsed" desc="Used Methods">
#Override
public void run()
{
while(true)
{
this.update();
this.repaint();
this.swap();
}
}
//Called from Thread to update movedImgArray prior to being drawn.
private void update()
{
//This is my attempt of trying to convert his code to java.
for (int i=img.getWidth(); i < imgArray.length - 1; i++)
{
if(i % img.getWidth() == 0 || i >= imgArray.length - img.getWidth())
continue;
buffer2[i] = (
((buffer1[i-1]+
buffer1[i+1]+
buffer1[i-img.getWidth()]+
buffer1[i+img.getWidth()]) >> 1)) - buffer2[i];
buffer2[i] -= (buffer2[i] >> 5);
}
//Still my version of his code, because of the int[] instead of int[][].
for (int y = 1; y < img.getHeight() - 2; y++)
{
for(int x = 1; x < img.getWidth() - 2; x++)
{
int xOffset = buffer1[((y)*img.getWidth()) + (x-1)] - buffer1[((y)*img.getWidth()) + (x+1)];
int yOffset = buffer1[((y-1)*img.getWidth()) + (x)] - buffer1[((y+1)*img.getWidth()) + (x)];
int shading = xOffset;
//Here is where the error occurs (after a click or wave started), because yOffset becomes -512; which in turn gets
//multiplied by y... Not good... -_-
movedImgArray[(y*img.getWidth()) + x] = imgArray[((y+yOffset)*img.getWidth()) + (x+xOffset)] + shading;
}
}
//This is my OLD code that kidna worked...
//I threw in here to show you how I was doing it before I switched to images.
/*
for(int y = 1; y < img.getHeight() - 1; y++)
{
for(int x = 1; x < img.getWidth() - 1; x++)
{
//buffer2[y][x] = ((buffer1[y][x-1] +
//buffer1[y][x+1] +
//buffer1[y+1][x] +
//buffer1[y-1][x]) / 4) - buffer2[y][x];
buffer2[y][x] = ((buffer1[y][x-1] +
buffer1[y][x+1] +
buffer1[y+1][x] +
buffer1[y-1][x] +
buffer1[y + 1][x-1] +
buffer1[y + 1][x+1] +
buffer1[y - 1][x - 1] +
buffer1[y - 1][x + 1]) / 4) - buffer2[y][x];
buffer2[y][x] = (int)(buffer2[y][x] * dampening);
}
}*/
}
//Swaps buffers
private void swap()
{
int[] temp;
temp = buffer2;
buffer2 = buffer1;
buffer1 = temp;
}
//This creates a wave upon clicking. It also is where that 512 is coming from.
//512 was about right in my OLD code shown above, but helps to cause the Exeception now.
#Override
public void mouseClicked(MouseEvent e)
{
if(e.getX() > 0 && e.getY() > 0 && e.getX() < img.getWidth() && e.getY() < img.getHeight())
buffer2[((e.getY())*img.getWidth()) + (e.getX())] = 512;
}
private BufferedImage back;
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
back.setRGB(0, 0, img.getWidth(), img.getHeight(), movedImgArray, 0, img.getWidth());
g.drawImage(back, 0, 0, null);
}
}
P.S. Here are two images of the old code working.
Looking at my original pseudocode, I assume the Array Out Of Bounds error is happening when you try to look up the texture based on the offset. The problem happens because the refraction in the water is allowing us to see outside of the texture.
for every pixel (x,y) in the buffer
Xoffset = buffer(x-1, y) - buffer(x+1, y)
Yoffset = buffer(x, y-1) - buffer(x, y+1)
Shading = Xoffset
t = texture(x+Xoffset, y+Yoffset) // Array out of bounds?
p = t + Shading
plot pixel at (x,y) with colour p
end loop
The way to fix this is simply to either clamp the texture coordinates, or let them wrap. Also, if you find that the amount of refraction is too much, you can reduce it by bit-shifting the Xoffset and Yoffset values a little bit.
int clamp(int x, int min, int max)
{
if (x < min) return min;
if (x > max) return max;
return x;
}
int wrap(int x, int min, int max)
{
while (x<min)
x += (1+max-min);
while (x>max)
x -= (1+max-min);
return x;
}
for every pixel (x,y) in the buffer
Xoffset = buffer(x-1, y) - buffer(x+1, y)
Yoffset = buffer(x, y-1) - buffer(x, y+1)
Shading = Xoffset
Xoffset >>= 1 // Halve the amount of refraction
Yoffset >>= 1 // if you want.
Xcoordinate = clamp(x+Xoffset, 0, Xmax) // Use clamp() or wrap() here
Ycoordinate = clamp(y+Yoffset, 0, Ymax) //
t = texture(Xcoordinate, Ycoordinate)
p = t + Shading
plot pixel at (x,y) with colour p
end loop

How to implement gaussian filter to downsample a image from 9x9 block into 5x5 of feature vector?

90x90 image is divided into 9x9 blocks with 8 chaincode direction and to minimize the feature downsample is required!! how can i downsample the image into 5x5 block using 5x5 gaussian filter. Is there a library function in java to implement gaussian filter.
I don't quite know what you are going for, but only for resizing the image, you could use AffineTransform at = AffineTransform.getTranslateInstance(x, y); and then at.scale(scaleX, scaleY); but I suppose you actually want to blur the image.
This is actually a quite simple process, I wrote a method for that once.
public BufferedImage blur(int range, int angle)
{
BufferedImage b = new BufferedImage(main_image.getWidth() * 2, main_image.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics2D g = b.createGraphics();
for(int x = 0; x < main_image.getWidth(); x++)
{
for(int y = 0; y < main_image.getHeight(); y++)
{
int red[] = new int[range * 2], green[] = new int[range * 2], blue[] = new int[range * 2];
int pixels[] = new int[range * 2];
for(int i = 0; i < pixels.length; i++)
{
pixels[i] = main_image.getRGB(clamp(x - clamp(range / 2, 0, range) + i, 0, main_image.getWidth() - 1), clamp(y - clamp(range / 2, 0, range) + (int)(i * Math.toRadians(angle)), 0, main_image.getHeight() - 1));
red[i] = (pixels[i] >> 16) & 0xff;
green[i] = (pixels[i] >> 8) & 0xff;
blue[i] = (pixels[i]) & 0xff;
}
int red_t = 0, green_t = 0, blue_t = 0;
for(int i = 0; i < pixels.length; i++)
{
red_t += red[i];
green_t += green[i];
blue_t += blue[i];
}
int r = red_t / (range * 2);
int gr = green_t / (range * 2);
int bl = blue_t / (range * 2);
//System.out.println(r + ", " + gr + ", " + bl);
g.setColor(new Color(r, gr, bl));
g.fillRect(x, y, 1, 1);
}
}
g.dispose();
return b;
}
This, is actually a pretty simple linear fiter. For a gaussian filter you would have to make the pixels, red, green and blue variable into a 2-dimensional array, and just repeat the whole procces for the y axis. If you understand, how the gaussian blue works, you should have no problem implementing this or changing it to a gaussian filter. If you want, you can ask me stuff about it.

How can i find the closest path in matrix that A to any B?

For example:
m_array = new int[6][6];
m_array[0] = new int[]{2, 0, 0, 0, 0, 0};
m_array[1] = new int[]{0, 2, 0, 0, 0, 2};
m_array[2] = new int[]{2, 0, 0, 1, 0, 0};
m_array[3] = new int[]{0, 0, 0, 0, 0, 0};
m_array[4] = new int[]{0, 2, 0, 0, 2, 0};
m_array[5] = new int[]{0, 0, 2, 0, 0, 0};
How can i find the the closest 2 to 1?
i want a function that it return an array path include points of array. For example i will give the "m_array" to my function and it will return to me the nearest 2 for 1, an array path like [2,3][3,4][4,4]
These are the things you leave us guessing:
there is only one 1, but many 2's;
the path allows diagonal steps;
you are looking for the shortest among all paths that connect the 1 with some 2.
My current thinking is that there is a metric that can be defined for the path length between any two points, so the concepts "a 2 with the shortest path to 1" is equivalent to the concept "the 2 closest to the 1". The metric can be defined as the number of "rings" around the central 1 one must cross to get to a 2:
0 0 0
0 1 0
0 0 2 --> the 2 is in the first ring
0 0 0 0 0
0 0 0 0 0
0 0 1 0 0
0 0 0 0 0
0 2 0 0 0 --> the 2 is in the second ring.
If all my assumptions are correct, then you need a function that gives all the members of the first ring, the second ring, and so on, and another function that will search a ring for a 2. Then, finally, you need an algorithm to draw a path to the 2. I hope you realize the path is not unique. A trivial algorithm will move diagonally until aligned (either horizontally or vertically) with the 2 and then continue non-diagonally to the target.
Unsure what you mean as you seem to be asking two different things. I can't really help on the path aspect as you didn't specify much criteria as to how we can move.
You also seem to be asking how to find the closest 2 to 1. Although not the most efficient, you could simply traverse the matrix and use Pythagoras' to work out the distance of each 2 to 1 based on the indices. Alternatively, you could traverse the matrix starting from your 1, outwards, in square shapes. This could be faster in that you would stop the second you find a 2, as opposed of having to traverse the whole matrix checking for 2s with the first solution, although first solution is easier to implement and shouldn't make that much difference given that your matrices are small (Both are O(n) I believe, however best case with the second way is that you can find a 2 with the first check whereas you always need to traverse whole matrix when using Pythagoras').
I hope this makes sense.
EDIT AFTER SOME CLARIFICATION:
Here is a method that I hope satisfies your requirements. First a class to wrap up the points for easy access.
public class Point {
private int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() { return x; }
public int getY() { return y; }
public int setX(int x) { this.x = x; }
public int setY(int y) { this.y = y; }
}
Now the method itself:
public ArrayList<Point> getPath(int[][] matrix) {
Point closestTwo = getClosestTwo(matrix); // Implement this as you wish
Point onePosition = getOnePosition(matrix);
ArrayList<Point> pointList = new ArrayList<Point>();
Point currentlyOn = onePosition;
while (currentlyOn.getX() != closestTwo.getX() && currentlyOn.getY() != closestTwo.getY()) {
currentlyOn = oneStep(currentlyOn, closestTwo);
pointList.add(currentlyOn);
}
return pointList;
}
Here is an example of oneStep method that you can use to get closer. It returns a point which would advance you the most while only doing one step (diagonals take priority).
public Point oneStep(Point from, Point goal) {
int x = from.getX() - goal.getX();
int y = from.getY() - goal.getY();
Point nextStep = new Point (from.getX(), from.getY());
if (x > 0) {
nextStep.setX(nextStep.getX() + 1)
} else if (x < 0) {
nextStep.setX(nextStep.getX() - 1)
}
if (y > 0) {
nextStep.setY(nextStep.getY() + 1)
} else if (y < 0) {
nextStep.setY(nextStep.getY() - 1)
}
return nextStep;
}
I believe this should work fine. You should get an ArrayList of Point if you use this.
An example of getClosestTwo method could be something like this (using Pythagoras'). Remeber to import java.lang.Math;
public Point getClosestTwo(int[][] matrix) { // Assumes matrix is initialized, non-empty etc.
int x, y;
double smallestDistance = matrix.size() * matrix[0].size(); // bigger than possible
Point onePosition = getOnePosition(matrix);
for (int i = 0; i < matrix.size(); i++) {
for (int j = 0; j < matrix[0].size(); j++) {
double tmp = (double)(Math.abs(i - y) + Math.abs(j - x))
double distance = Math.sqrt(tmp);
if (distance < smallestDistance) {
y = i;
x = j;
smallestDistance = distance;
}
}
}
return new Point(x, y);
}
getOnePosition(int[][] matrix) can be simply implemented like so:
// Return null if no 1 in matrix
public Point getOnePosition(int[][] matrix) {
for (int i = 0; i < matrix.size(); i++) {
for (int j = 0; j < matrix[0].size(); j++) {
if (matrix[i][j] == 1) {
return new Point(j, i);
}
}
}
return null;
}
Hope this helped. Remember to check for nulls, write safe code etc. etc. You can probably put this all together. I hope there aren't any typos or errors with this code that you won't be able to fix.
I prefer quickgraph for find closer points or paths ;
So,Please see this link:
http://www.codeproject.com/Articles/5603/QuickGraph-A-100-C-graph-library-with-Graphviz-Sup
This function splice my matrix array as ring radius.
public static int[][] SpliceMatrix(int orginX, int orginY, int ringRadius, int[][] map){
int[][] tempMap = new int[ringRadius * 2 + 1][ringRadius * 2 + 1];
int tempY = -ringRadius;
for(int i = 0; i < (ringRadius * 2 + 1); i++){
int tempX = -ringRadius;
for(int j = 0; j < (ringRadius * 2 + 1); j++){
try{
tempMap[i][j] = map[orginY + tempY][orginX + tempX];
}catch(ArrayIndexOutOfBoundsException e){
tempMap[i][j] = 1;
}
tempX++;
}
tempY++;
}
return tempMap;
}
I used the A* algoritm in this function:
private static Point findNext2(int orginX, int orginY, int[][] map){
//Find "2"s
ArrayList<Point> ends = new ArrayList<Point>();
for(int i = 0; i < map.length; i++){
for(int j = 0; j < map[0].length; j++){
if(map[i][j] == 2){
ends.add(new Point(j, i));
map[i][j] = 0;//Clear for A*
}
}
}
//Find the closest
if(ends.size() > 0){
Point p = null;
int distance = 100;
for(int i = 0; i < ends.size(); i++){
int tempDistance = APlus.go(orginX, orginY, ends.get(i).x, ends.get(i).y, map).size();
System.out.println(tempDistance);
if(tempDistance != 0 && tempDistance < distance){
distance = tempDistance;
p = new Point(ends.get(i).x, ends.get(i).y);
}
}
if(p == null){
System.out.println("2 is not accesible");
return null;
}
return p;
}else{
System.out.println("There is no 2 in ring");
return null;
}
}
Then i use
public static void main(String args[]){
int[][] m_array = new int[6][6];
m_array[0] = new int[]{1, 1, 0, 0, 2, 0};
m_array[1] = new int[]{0, 0, 0, 0, 0, 1};
m_array[2] = new int[]{1, 1, 1, 0, 1, 0};
m_array[3] = new int[]{1, 0, 1, 0, 1, 0};
m_array[4] = new int[]{0, 0, 0, 0, 1, 0};
m_array[5] = new int[]{0, 0, 0, 0, 0, 0};
int[][] c = SpliceMatrix(2, 2, 2, m_array);//int x, int y, ringRadius, matrix
Point p = findNext2(3, 3, c);//orginX, orginY, matrix
System.out.println(p + " is the closest 2");
}
I hope that was descriptive. I can't using the HTML correctly yet.
Here's my piece of code. Seems way simpler than anything I saw here so decided to post:
public static boolean isWithinRadius(int[] position, int[] centerPosition, int radius) {
int xCenterPoint = centerPosition[0];
int yCenterPoint = centerPosition[1];
int zCenterPoint = centerPosition[2];
int xPoint = position[0];
int yPoint = position[1];
int zPoint = position[2];
boolean xMatch = (xPoint - radius <= xCenterPoint) && (xPoint >= xCenterPoint - radius);
boolean yMatch = (yPoint - radius <= yCenterPoint) && (yPoint >= yCenterPoint - radius);
boolean zMatch = (zPoint - radius <= zCenterPoint) && (zPoint >= zCenterPoint - radius);
return xMatch && yMatch && zMatch;
} // public boolean isWithinRadius (int[], int)
This will return true if a position is within the radius of the centerPosition.
centerPosition is the center of the rings. (If you don't need Z value, just put 0 anywhere it is asked for.)
Radius 1 == Ring 1 , Radius 2 == Ring1 & Ring 2. etc. You can scan the radius. Try to build on that. If you are interested, I've wrote an advanced Matrix Class to which you can scan(hash based) and find objects within it.
I was just about to write the code that returns an ArrayList of objects found within a radius.
If you wish to find objects only within a specific ring (rather than all objects within a radius) use this code:
public static boolean isWithinRadiusRing(int[] position, int[] centerPosition, int radius) {
int xCenterPoint = centerPosition[0];
int yCenterPoint = centerPosition[1];
int zCenterPoint = centerPosition[2];
int xPoint = position[0];
int yPoint = position[1];
int zPoint = position[2];
boolean xRingMatch = (xPoint - radius == xCenterPoint) || (xPoint == xCenterPoint - radius);
boolean yRingMatch = (yPoint - radius == yCenterPoint) || (yPoint == yCenterPoint - radius);
boolean zRingMatch = (zPoint - radius == zCenterPoint) || (zPoint == zCenterPoint - radius);
boolean xRadiusMatch = (xPoint - radius <= xCenterPoint) && (xPoint >= xCenterPoint - radius);
boolean yRadiusMatch = (yPoint - radius <= yCenterPoint) && (yPoint >= yCenterPoint - radius);
boolean zRadiusMatch = (zPoint - radius <= zCenterPoint) && (zPoint >= zCenterPoint - radius);
boolean xMatch = xRingMatch && yRadiusMatch && zRadiusMatch;
boolean yMatch = yRingMatch && xRadiusMatch && zRadiusMatch;
boolean zMatch = zRingMatch && xRadiusMatch && yRadiusMatch;
/*
System.out.println("xRingMatch="+xRingMatch+" yRingMatch="+yRingMatch+" zRingMatch="+zRingMatch);
System.out.println("xRadiusMatch="+xRadiusMatch+" yRadiusMatch="+yRadiusMatch+" zRadiusMatch="+zRadiusMatch);
System.out.println("xMatch="+xMatch+" yMatch="+yMatch+" zMatch=" +zMatch);
System.out.println("return=" + (xMatch || yMatch || zMatch));
*/
return xMatch || yMatch || zMatch;
} // public boolean isWithinRadiusRing(int[], int[] , int)
This will return true if the given position is within a given radius ring from centerPosition (radius 1 == ring1, radius 2 == ring 2, etc.)
To find out the Radius Distance between two positions:
public static int getDistanceRadius(int[] startPosition, int[] endPosition) {
// The xyz value that streches the most the distance between two positions
// is the radius value.
int xDistance = Math.abs(startPosition[0] - endPosition[0]);
int yDistance = Math.abs(startPosition[1] - endPosition[1]);
int zDistance = Math.abs(startPosition[2] - endPosition[2]);
int radius = (xDistance > yDistance ? xDistance : yDistance);
radius = (radius > zDistance ? radius : zDistance);
return radius;
} // public static int getDistanceRadius(int[], int[])

Categories