Generating a filled polygon inside a hyperarray - java

Consider the following:
Currently, I'm programming a very basic dungeon generator. Right now, it works like this:
Generate an int[][] hyperarray of arbritrary lengths.
Place rooms at random coordinates in this hyperarray (we'll call it maze for now.) using a for loop that fills the heigth and width of the room with 1's in maze. For game engine purposes 0 means not traversable (a wall.) and 1 means traversable by the player/enemies.
Start a perfect maze generator at 0,0 and run until all the space inbetween the rooms is filled with corridors.
Connect rooms to corridors, remove dead ends, you're left with a system of interconnected rooms.
Like this
Now I'd like to jazz up these rooms because they're just flat rectangles. What I now need to do is find a way to generate a polygon inside the int hyperarray (coordinates will probably do fine, this isn't the problem) and then fill the space of the polygon in the hyperarray with 1's (the part I'm having trouble with).

I'm trying to figure out how to "draw lines within a integer array" right now.
what i found out was, i could draw a line from one point to another, by doing the following:
find the width and height of point 1 and point 2 (absolute value of x1-x2 and y1-y2,
divide width by (height-1) and from point 1 to point 2, along the y axis move towards point 2 by single steps, and on the x axis by width / height steps.
Example:
01000
01000
00100
00100
00010
00001
here i have a line from (1,0) as (x,y) to (4,5)
if i take the width and height i end up with
width = 3
height = 5
if i divide 3/5 i end up with 0.6
and so for every single step along the y axis, i take a 0.6 step along the x axis (and floor the resulting value, since we can only use integers as positions)
and end up with the koordinates
(1,0)
(1.6,1) -> (1,1)
(2.2,2) -> (2,2)
(2.8,3) -> (2,3)
(3.4,4) -> (3,4)
(4,5) -> (4,5)
with this you could draw those lines for every coordinate pair of the polygon using this line function
x = x1 + (|(y1-y)| * ( |(x1-x2)| / |(y1-y2)| ) * sign(x2-x1))
where x is the current x of every iteration, following the line along the y axis
and x1 beeing your start x position, x2 beeing your end position
y beeing the current y of every iteration (the actual counter during the loop to be specific)
y1 and y2 beeing the start y and end y positions repectively.
and sign(x2-x1) to help figure out, wether you are going to the left or right from the start position.
with this you should be able to draw the outline of your polygon, and hopefully it should become easier to fill it afterwards.
i hope this helps you a bit
regards
EDIT:
we draw lines for every consecutive pair of coordinates, not EVERY SINGLE pair.
meaning if you would draw a polygon from points p1,p2,p3,p4,p5
you would draw a line from p1 to p2, p2 to p3, p3 to p4, p4 to p5 and p5 to p1
just a quick sidenote

Related

Shortest path problem inside a grid structure

I'm working on a basic program where 2 players on a 2D board of size 30x30 have to reach a smaller grid of size A*A (let's call it rug) somewhere on the 2D board. I need to calculate which of the players is closer to the rug. I know how to calculate the distance to the top left corner of the rug (as i use x and y coordinates to draw it), but don't know how to calculate the distance to the nearest point of the rug, which could also e.g be the middle of the bottom of the rug.
This is more of an algorithms question than java. Could you clarify the information we have about the rug? Do we have the rug's coordinates? Do we have the player's coordinates?
Assuming you had the coordinates of the corners of a square A*A rug, you could simply compute which player has a shorter Euclidean distance to the rug corners, or its sides. This can be done by creating a list of coordinates the rug owns.
Bear in mind this is psuedo code, please do not just copy the code into your IDE and be upset it didn't pass your tests.
So again the steps are:
Create a list of square rug's coordinates
Add corners to that list
Compute the points along the sides of the rug to be added to the list
Compare the minimum euclidean distance between the players and ALL coordinates in the list. The lower distance is closest.
Let's suppose you had a unit square rug with corners at (1,1), (-1,1), (-1,-1), (1,-1).
ArrayList<String> rugCoordinates = new ArrayList<String>();
//first add all corners
rugCoordinates.add("(1,1)");
rugCoordinates.add("(-1,1)");
rugCoordinates.add("(-1,-1)");
rugCoordinates.add("(1,-1)");
Now you need to add the points along the line to the list. You can get the slope between the points via rise/run for example, between (-1,1) and (1,1) = 0 slope.
slope = (yCoordTarget-yCoordSource)/(xCoordTarget-xCoordSource);
for(int i = xCoordSource; i < xCoordTarget, i++){
rugCoordinates.add(i, i+slope);
}
Finally compare the min distances of players.
if (findMinEuclideanDistance(player1) < findMinEuclideanDistance(player2)){
return player1;
else{
return player2;
}

How to find the corresponding subtriangle of a position inside a rectangle

I have a dynamic rectangle in which 4 subtriangles (t0-t3) are created (by adding the diagonals from the vertices). When given a certain x|y coordinate what is the fastest way to find the corresponding triangle?. The rectangle has a specific position and dimension. I only need the right "id" so not the vertices of the triangle, so for example in the graphic when p1 is given as position 0 should be returned, 3 at p2 and 2 at p3, ...
One possible solution of course would be to create the triangles and query if the point is contained in one of them, but it feels like a very complicated solution for something that simple.
I also thought about creating a vector from the center and measuring the angle but it also seems complicated in a rectangle with varying dimensions.
Example Rectangle
Consider the following:
Let the bottom left corner of the rectangle be (0,0) and the top right corner be (1,1). Now, the two lines that form the triangles are defined as:
y = x and y = 1-x
For every point except (.5,.5) we have a ternary conditional for a given x or y. For example, given that x = .2, we know that:
if y < .2, we're in the bottom triangle (t2),
elif .2 < y < .8, we're in the left triangle (t3),
else, we're in the top triangle (t0).
Hopefully this helps without explicitly giving you the code.

How to use trig to spawn an object in "front" of the player object

What I am trying to convey in the title, is that there is a player on the screen and, using the direction variable and trigonometry, he is "looking" in a direction. I need to spawn an object right in front of him. And by spawn, I mean create an object with the x and y coordinates matching the location of the spot in "front" of the player.
The code for this is something difficult. I'm unable to understand, without more information or learning more trig, what I need to do to get this to work.
Basically this is what I have, it creates a bullet and another line of code adds it to a list to be drawn to the screen. What I need to know is how to spawn the "bullet" object in the correct x & y coordinates. This is what I have so far. I can assume there is something more I need to add to the x and y variables, but I don't know what that is.
Bullet b = new Bullet((int)x/2+(Math.cos(Math.toRadians(direction))), (int)y/2 + (Math.sin(Math.toRadians(direction))), "/img/bullet.png", direction, weapon);
Create a vector pointing in a direction where you want the object spawned.
x = radius * Math.cos(angle) + startX
y = radius * Math.sin(angle) + startY
Normalize it, and then scale it to your liking.
Here's a simple demo to illustrate.
p.s
radius here is just an initial uniform displacement from the spawn point.
It would help if you understood Proportionality, but it is basically this: if you multiply x and y for the same number, you will get farther away from the current position. Of course that depends on the signals, but the simplest way is this: supposing that x and y are two positive numbers, let's say x=1 and y=1, then, if you multiply both by a positive number, let's say 3, then the final numbers (x=3 and y=3) you will have a "bullet" in the coordinates 3,3 that is right in front of the actor, which is in the position 1,1. Again, I am assuming a lot of things and ignoring a bunch of other ones, such as position of camera, perspective, etc.

Collision Handling... Confused where to go

So, I'm working on a 2D physics engine, and I have an issue. I'm having a hard time conceptualizing how you would calculate this:
Take two squares:They move, collide, and at some vector based off of the velocity of the two + the shape of them.
I have two vector lists(2D double lists) that represent these two shapes, how does one get the normal vector?
The hit vector is just (s1 is the first shape, s2 the second) s2 - s1 in terms of the position of the center of mass.
Now, I know a normal vector is one perpendicular to an edge, and I know that you can get the perpendicular vector of a line by 90 degrees, but what edge?
I read in several places, it is the edge a corner collided on. How do you determine this?
It just makes no sense to me, how you would mathematically or programmatically determine what edge.
Can anyone point out what I'm doing wrong in my understanding? Sorry for providing no code to explain this, as I'm having an issue writing the code for it in the first place.
Figure1: In 2D the normal vector is perpendicular to the tangent line:
Figure2: In 3D the normal vector is perpindicular to the tangent plane
Figure3: For a square the normal vector is easy if you are not at a corner; It is just perpendicular to the side of the square (in the image above, n = 1 i + 0 j, for any point along the right side of the square).
However, at a corner it becomes a little more difficult because the tangent is not well-defined (in terms of derivatives, the tangent is discontinuous at the corner, so perpendicular is ambiguous).
Even though the normal vector is not defined at a corner, it is defined directly to the left and right of it. Therefore, you can use the average of those two normals (n1 and n2) as the normal at a corner.
To be less technical, the normal vector will be in the direction from the center of the square to the corner of the collision.
EDIT: To answer the OP's further questions in the chat below: "How do you calculate the normal vector for a generic collision between two polygons s1 and s2 by only knowing the intersecting vertices."
In general, you can calculate the norm like this (N is total verts, m is verts inside collision):
vcenter = (∑N vi) / N
vcollision = (∑m vi) / m
n = vcollision - vcenter
Fig. 1 - vcollision is only a single vertex.
Fig. 2 - vcollision is avg of two verts.
Fig. 3 - vcollision for generic polygon intersection.

Using a QuadTree to get all points within a bounding circle

I have a set of 100 to 200 points (x,y). I have to check which ones fall within a particular distance of the others. The particular distance is fixed for the entire program, say 50. Say point 1 falls within the range of points 5,7,25,90,96,105...etc. Similarly point 2 falls within range of 23,45, etc...
Storing objects for locating by x,y coordinates
Here QuadTree is suggested, but it can be used to get all the points within a bounding rectangle. But how to get all points within a bounding circle? there is a method which returns a point closest to a lat/long within a maximum distance, but how to get all the points within the distance?
http://openmap.bbn.com/doc/api/com/bbn/openmap/util/quadtree/QuadTree.html#QuadTree(float, float, float, float, int)
one way maybe to remove each point from the tree as I get it, then query for the closest point again, until i get null. is that the only way?
Suppose that you have a circle centered at (x, y) with radius r and want to find all points in a quadtree that are in the circle. One idea is as follows:
Construct the bounding box inscribing the circle. This is the smallest rectangle containing the circle, which has upper-left corner (x - r, y - r) and lower-right corner (x + r, y + r). Any point in the circle must also be in the square, but not the other way around.
Query the quadtree for the set of points lying in that rectangle. Let these points be P.
For each point in P which is known to be in the rectangle, see if it is also in the circle. You can do this by checking whether the distance from that point to (x, y) is no greater than r. In other words, given a point (x0, y0), you would compute (x - x0)2 + (y - y0)2, and if this value is less than or equal to r2, then the point is contained in the circle.
Although this may seem inefficient, it's actually quite fast. The ratio of the area of the square to the area of the circle is 4 / π &approx; 1.27. In other words, assuming that your points are distributed somewhat evenly, you'll only find about 27% more points than you need to.

Categories

Resources