For hidden object game collision detection,the following code using zengl
generates points around the edges of a texture(for design time):
tex_GetData(txtr, myData );
for h:=0 to txtr.Height-1 do
begin
for w:=0 to txtr.Width-1 do
begin
if (PByte(Ptr(myData) + w* 4 + h * realWidth * 4 +3)^>50)and (PByte(Ptr(myData) + w* 4 + h * realWidth * 4 +3)^<150) then
begin
inc(counter);
if counter mod (cn)=0 then
if cntr<>100 then
begin
inc(cntr);
// setlength(points,(cntr+1));
points[cntr].X:=w;
points[cntr].y:=w;
end ;
The problem is about making a polygon from the given points. The polygon is drwan in the wrong way.
Now trying to detect first pixels all along each edge by iterating through
width(0 to width)and each time the width increase by one height will iterate from top(=0)until hits first none transparent pexil and will reset to zero when the width will increase by one until scanning the top region.
loops do not work well here:
//Top
w:=1;
h:=1;
for w:=0 to texture.Width-1 do
while(h<txtr.Height-2)do
begin
if (PByte(Ptr(myData) + w* 4 + h * realWidth * 4 +3)^)=255 then
begin
inc(h);
inc(cntr);
setlength(points,(cntr+1));
points[cntr].X:=w;
points[cntr].y:=h;
continue;
end;
break;
end ;
But it stops half way.
My desire is to make the iteratation through the array of points that draw a polygon lines to take the closest shape :
for i:=1 to length(points)-1 do
begin
pr2d_Line(points[i].X,points[i].y,points[i+1].X,points[i+1].y,$FF0000,255);
End;
I hope to see a example for the correct looping.
Update
if (PByte(Ptr(myData) + w* 4 + h * realWidth * 4 +3)^)=255 then
The above line is only to detect none transparent pixels in pbytearray and it works (if pixel[w,h] is not transparent then).
Just looking for the first none transparent pixel in an image by scanning every pixel in it by rotating its bounds for example:
scan top from right to left, scan Right from top to bottom, scan bottom from right to left, and finally scan left from bottom to top.
Not sure if that is called vector, but will generate one array of points called with one loop and if its points are connected the result will be a polygon takes the same shape of the raster.
Related
I encountered this challenge in
codesignal (The core, question 49).
Here is the problem:
A rectangle with sides equal to even integers a and b is drawn on the Cartesian plane. Its center (the intersection point of its diagonals) coincides with the point (0, 0), but the sides of the rectangle are not parallel to the axes; instead, they are forming 45 degree angles with the axes.
How many points with integer coordinates are located inside the given rectangle (including on its sides)?
Example:
I also have the solution in JS, by another user:
function solution(a, b) {
var pointsA = Math.floor(Math.sqrt(a * a / 2)),
pointsB = Math.floor(Math.sqrt(b * b / 2));
return (pointsA * pointsB + Math.floor((pointsA + pointsB) / 2)) * 2 + 1;
}
However I cannot understand it. Although the theme of the challenge is nested loop, I still want to understand the math behind this solution. Please explain it to me. Thank you.
The diagonal of a grid cell has length √2. So the number of oblique rows contained in the rectangle is determined by the integer parts of a/√2 and b/√2. The count of grid nodes is just the product of these numbers of rows, with an adjustment term that accounts for the parities of every other row.
This question already has answers here:
Fitting largest circle in free area in image with distributed particle
(5 answers)
Closed 1 year ago.
I deal with plots of data on the order of half a million points in Octave. I am trying to find the center of empty spaces that are in the data (on purpose).
I know how many points to look for and I was thinking of feeding in starter locations and then try to expand a circle in one direction until you hit valid data point locations and keep doing that in a few directions until you have a circle that is filled with no data but touches valid data points. The center of that circle would be the center of the void space. I'm not entirely sure how to write that since I'm very green in coding.
Obviously a graphical solution probably isn't the best method, but I don't know how to find big x and y gaps in a huge matrix of x y locations.
A section of the data I deal with. Trying to write a program to automatically find the center of that hole.
A sample of the data I'm working with. Each data point is an x and y location with a z height that isn't really valuable to what I'm trying to solve here. The values do not line up in consistent intervals
Here is a large sample of what I'm working with
I know you said your data does not line-up in x or y, but it still seems suspiciously grid-like.
In this case, you can probably express each gridpoint as a 'pixel' in an image; this gives you access to excellent functions you can use from the image package, such as the imregionalmin function. This will give you connected components of 'holes', in your case. For each component you can find their centres of mass easily by finding the 'average coordinate' over the pixels within that component. You can then perform a distance transform (e.g. using bwdist) to find the exact radius for the circle you describe, as the distance from that centre of mass to the nearest pixel. Alternatively, you can start with bwdist and then use immaximas to detect the centres of mass directly. If you have multiple such regions, you can use bwconncomp to find connected components first (or over the output of imregionalmin).
If your data is not specifically grid-like, then you could probably interpolate your data to make them fit such a grid.
Example:
pkg load image
t = 0 : 0.1 : 2 * pi; % for use when plotting circles later
[X0, Y0] = ndgrid( 1:100, 1:100 ); % Create 'index' grid
X = X0 - 0.25 * Y0; Y = 0.25 * X0 + Y0; % Create transformed grid
Z = 0.5 * (X0 - 50) .^ 2 + (Y0 - 50) .^ 2 > 250; % Assign a logical value to each 'index' point on grid
M = imregionalmin ( Z ); % Find 'hole' as mask
C = { round(mean(X0(M))), round(mean(Y0(M))) }; % Find centre of mass (as index)
R = bwdist( ~M )(C{:}); % Find distance from centre of mass to nearest pixel
R = min( abs( X(C{1}+R, C{2}) - X(C{:}) ), abs( Y(C{1}, C{2}+R) - Y(C{:}) ) ); % Adjust for transformed grid
figure(1); hold on
plot( X(Z), Y(Z), '.', 'markerfacecolor', 'b' ) % Draw original transformed grid data
plot( X(C{:}), Y(C{:}), 'o', 'markerfacecolor', 'r' ); % Draw centre of mass in transformed grid
plot( X(C{:}) + R * cos(t), Y(C{:}) + R * sin(t), 'r-' ) % Draw optimal circle on top
axis equal; hold off
-Create a sketch of 10 concentric squares of different colors
-Incorporate user input when the mouse or keyboard is pressed changed the colors of the squares
-Code must use variables/ loops/ and decision structures.
If your problem is having them be concentric, use rectMode()
rectMode(CENTER);
for (int i = 0; i < 10; i++) {
rect(width / 2, height / 2, 10 * (i + 1));
}
The term concentric, while usually used for circles, is actually just based on the Latin for "same centre". Hence concentric squares are just those that have the same center (where the diaganols meet).
So, let's say you need the upper left corner (where X increases across to the right, Y increases down to the bottom) and side length. To work out the center of an existing square:
centX = X + length / 2
centY = Y + length / 2
Then to work out the upper left co-ordinates for a new square of given length (that's concentric with the first):
X = centX - length / 2
Y = centY - length / 2
You can wrap that up in a function (pseudo-code) with somwething like:
def makeConcentricSquare(origX, origY, origLen, newLen):
newX = origX + origLen / 2 - newLen / 2
newY = origY + origLen / 2 - newLen / 2
return (newX, newY, newLen)
This is, of course, assuming your squares are horizontal in nature. You can do similar things to rotate them but I'll leave that as an exercise for the reader, especially since the specifications make no mention of allowing for it :-)
I have an n-sized collection of Rects, most of which intersect each other. I'd like to remove the intersections and reduce the intersecting Rects into smaller non-intersecting rects.
I could easily brute force a solution, but I'm looking for an efficient algorithm.
Here's a visualization:
Original:
Processed:
Ideally the method signature would look like this:
public static List<RectF> resolveIntersection(List<RectF> rects);
the output would be greater or equal to the input, where the output resolves the above visual representation.
Sweepline algoithms are good at processing intersections in 2D universes. I mean consider an horizontal line moving down from a rectangle edge to the next rectangle edge. The line hits a number of rectangles, forming the so-called active lists. The active list is kept updated at every move.
By studying the ranges of abscissas along the horizontal line, you can detect the overlaps.
A careful study of all configurations should allow you to split the rectangles the way you want in a single sweep, with lower complexity than brute force (closer to N^1.5 than to N^2).
this is a problem I solved in the past. The first thing it to sort the rectangles using the x or y value of one of the edges. Lets say you order in the y-direction and use the top edge. The topmost rectangle in your example is first in sorted order. For each rectangle you know its size in the y-direction.
Now, for each entry (call it the the current entry, it corresponds to a rectangle)in the sorted list you search forward through the list until you reach an entry greater than the current entry + the corresponding rectangle size. (call it the stopping entry)
Any entries in the sorted list between the current entry and this stopping entry will be potential intersections. Simply check if the rectangles x-ranges intersect.
When choosing to sort in the x or y direction, it will be better to choose the dimension that is larger as this will imply fewer intersection on average so less checking.
Here is an example. Rectangles are defined as R(x1,x2,y1,y2) where x1 is the left side, x2 is right side, y1 is top and y2 is bottom
rectangle 1 (1,5,0,4)
rectangle 2 (7,9,6,8)
rectangle 3 (2,4,2,3)
rectangle 4 (3,6,3,7)
rectangle 5 (3,6,9,15)
sort according to y1 to give
# y1 size
rectangle 1 0 4
rectangle 3 2 3
rectangle 4 3 4
rectangle 2 6 2
rectangle 5 9 6
so, rectangle 1 has y1 + size = 0 + 4 = 4 implying it will potentially intersect rectangle 3 (y1 value = 3 < 4) and rectangle 4 (y1 value = 3 < 4) but not rectangle 2 (y1 value = 6 > 4)...no need to check any rectangels in the list after 2
Rectangle 3 has y2 + size = 2 + 3 = 5 implying it will potentially intersect rectangle 4 (y1 value = 3 < 5) but not recatngle 2 (y1 value = 6 > 5) no need to check any rectangels in the list after 2
Rectangle 4 has y2 + size = 3 + 4 = 7 implying it will potentially intersect rectangle 2 (y1 value = 6 < 7) but not recatngle 5 (y1 value = 9 > 7)
Of course, with large numbers of rectangles you will generally only have to check a fraction of the possible pairs for intersection.
what you're descrbing is the packing problem, have a look at wikipedia
it refers to this article describing an algorithm for packing rectangles in rectangles
this is from the article:
This article describes a fast algorithm to pack a series of rectangles of varying widths and heights into a single enclosing rectangle, with no overlap and in a way that minimizes the amount of wasted space in the enclosing rectangle.
I have problem with circle-rectangle intersection.Though A number
of discussion i found about it ,i could not get my answer.My problem is -I have a rectangle lower portion(100-200,0-50) of my view/window(320 X 480).And a ball is moving here and there.And
sometimes it collides with the rectangle and bounce back.And my problem is how will i know in which axis circle collide with the
rectangle, in x-axis or y axis,means in which line(x=100 or x=200 or y==50) circle intersect with rectangle.
*Ball comes from outside of rectangle.
To see if it hits one of the lines full on is easy: just check for a collision between the bounding box of the circle and each of the lines in turn.
The problem is if it hits a corner... then you have to intersect the circle with each line. This can be done, but requires a bit more mathematics. It will also bounce off at an unusual angle.
Say the ball's center is moving along a time trajectory that can be described as x = a t + b and y = c t + d -- any linear, uniform-speed motion can be described this way. Since you say that it's initially (say at t=0) outside the rectangle, we know that at that time x < 100 or x > 200, or y < 0 or y > 50 (one of the conditions of x, and one of the conditions of y, can both be true, but at least one must be -- if they were all false we'd be inside the rectangle).
So check "at what time and exactly where will that point intersect each of the four lines that make up the rectangle"; i.e., solve for t when x = 100 (which gives t = (100 - b) / a, and therefore y = c (100 - b) / a + d), x = 200, y = 0, y = 50. Discard the solutions where t < 0 (those were things that happened in the past), as well as ones where the other variable falls outside of the rectangle's boundaries (for example, for the t = 100 case I just mentioned, you can ignore the apparent solution if (100 - b) / a < 0, or c (100 - b) / a + v < 0, or c (100 - b) / a + v > 50). If none of the four is left, this means the ball (with a radius of 0...) will not hit the rectangle along its current trajectory (it may if and when it bounces and thus changes trajectory, but those will be separate computations). If one or more are left, the one with the minimum value of t is the one you want. Once you know where and when the center would hit the rectangle, taking account of the radius can be done separately, but won't change the issue of which rectangle side the ball hits.
The cases where the ball "glances" (hits the rectangle just because it does have a radius greater than zero) are harder, but one approach is, if the normal computation shows the ball "not hitting", repeat it after shifting the ball (by the amount of its radius) to both side of the trajectory-line it's following -- this will tell you if the ball IS in fact going to hit, and, if so, which side (assuming hits on corners can be counted as hits on one of the sides converging on that corner;-).
How about:
Let centre of circle have coordinates cx, cy, radius cr.
if cx > 100 - cr and cx <= 100 and cy <= 50
collision with left upright
else if cy >= 50 and cy < 50 + cr and cx > 100 and cx < 200
collision with top
else if cx < 200 + cr and cx >= 200 and cy <= 50
collision with right upright
else if ( cx - 100 ) ** 2 + ( cy - 50 ) ** 2 < cr ** 2
collision with top left corner
else if ( cx - 200 ) ** 2 + ( cy - 50 ) ** 2 < cr ** 2
collision with top right corner
else
no collision
Corner collisions will need special treatment to work out how bounce will work based on exact point of contact and direction of travel. This also leaves a large part of the screen where collisions will not be detected (inside the rectangle), which I'm sure you could add to the above algorithm.
Doing a quick search seems to indicate that this problem has been asked before...
decrease rectange by size of radius on each side and move circle as point.