Gestures and Rectangles - xna

I'm trying to create a word search game (kind of like Wordament but much simpler).
I figure I would display my text (word jumble) using the spriteBatch.DrawString. Then I would draw rectangles over the letters and then read the words inside the rectangles...
My first issue is trying to draw the rectangles using the free drag gesture. I've tried several examples of drawing rectangles, but they all are in the "draw" method. Not in the HandleTouchInput method (I found this method for handling gestures).
I guess my question has two parts.
Can I accomplish what I want described above? Using spriteBatch.DrawString and rectangles to read the letters selected?
If so, how do I draw rectangles using gestures?
If you have examples or suggestions please let me know.
Thanks!

Generally, you're not going to want to draw anything in the HandleTouchInput method. Instead, you handle the input, and create a new sprite to be drawn later in the sprite batch. Something like the following pseudo-code:
HandleTouchInput(vector2d begin, vector2d end)
{
sprite tempRectangle = new Rectangle(begin, end);
string foundLetters;
//search through the letters in your puzzle to find which ones were selected in the rectangle
foreach(letter in wordPuzzleSprites)
{
//if you found one, then add it to the list of letter that were selected
if(letter.isWithin(tempRectangle))
{
foundLetters.add(letter.letterCharacter());
}
}
//check your found letter against the list of words
foreach(word in wordPuzzleList)
{
if(foundLetters == word)
{
//mark the word as found, and add the rectangle sprite to the collection of sprites to be drawn
CollectionOfSprites.add(tempRectangle);
}
}
}

Related

Divide a Tchart into equal parts and then draw rectangles on it in Firemonkey

I have a simple program in C++ builder with VCL that i need to migrate to Firemonkey. In this application i need to draw on a TChart, but i don't know how to get it to work. My application is really simple; a user inputs data in a stringgrid and then the data is displayed in two different TChart by clicking two different buttons.
The first button click is to divide the TChart into equal parts (generally in two parts, but the user can divide the TChart into more than two parts). In the first example there is a column, with two long rectangles with texts, in it. In this example it's two rectangles with "CH PL".
The second button is supposed to draw on the same TChart this:
It's essentially two or more rectangles which go from the beginning of the chart until the end.
To make it simple i need to divide the TChart into two or more equal parts horizontally and then draw rectangles with texts on it, which is the simplest solution.
I'm really lost because by searching on the net i came across a similar problem by simply using the TChart.AfterDraw() method, but I don't know how to use it, it's not really clear.
The drawing are generated once the user clicks a button, else there should be nothing.
My method for drawing so far:
void __fastcall TForm1::rbComprChange()
{
Series5->Clear(); //used for clearing the series to regenerate them from the user input
for(int i=0;i<StringGrid1->RowCount;i++)
{
Series5->AddGantt(StrToDate(StringGrid1->Cells[4][i]),StrToDate(StringGrid1->Cells[5][i]),i,StringGrid1->Cells[1][i]);
Series5->NextTask->Value[i]=i;
}
// How and where should i draw these rectangles?!
}
Can someone guide me or explain to me how to do that either in C++ Builder or Delphi.

iOS - Find white pixels/area enclosed by a black curve and create path

Using Swift methods touchBegan, touchMoved and touchEnded I save the touch points and than I draw a line using UIGraphicsGetCurrentContext() with methods beginPath(), move(to: Point), addLine(to: Point) and strokePath().
This line is repeated on 4 quadrants plus their negative values, therefore 8 lines are drawn.
Here is an example:
Example image
I save this drawing as an Image when the user taps the tick (Done green button at top-right) for later manipulations.
I wonder if it's possible to create e closed path/shape with white pixels enclosed by the black lines. I want to fill the white area with custom color when the user touches inside it.
The shape is created by user input and I have no idea how it would look like.
Would be thankful to whoever finds the time to give it's contribute.
Thank you
Maybe what you want is the "Flood Fill" algorithm, please see the article.

Edge detection on pool table

I am currently working on an algorithm to detect the playing area of a pool table. For this purpose, I captured an image, transformed it to grayscale, and used a Sobel operator on it. Now I want to detect the playing area as a box with 4 corners located in the 4 corners of the table.
Detecting the edges of the table is quite straightforward, however, it turns out that detecting the 4 corners is not so easy, as there are pockets in the pool table. Now I just want to fit a line to each of the side edges, and from those lines, I can compute the intersects, which are the corners for my table.
I am stuck here, because I could not yet come up with a good solution to find these lines in my image. I can see it very easily when I used the Sobel operator. But what would be a good way of detecting it and computing the position of the corners?
EDIT: I added some sample Images
Basic Image:
Grayscale Image
Sobel Filter (horizontal only)
For a general solution, there will be many sources of noise: problems with cloth around the rails, wood texture (or no texture) on the rails, varying lighting, shadows, stains on the cloth, chalk on the rails, and so on.
When color and lighting aren't dependable, and when you want to find the edges of geometric objects, then it's best to think in terms of edge pixels rather than gray/color pixels.
A while back I was thinking of making a phone-based app to save ball positions for later review, including online, so I've though a bit about this problem. Although I can provide some guidance for your current question, it occurs to me you'll run into new problems each step of the way, so I'll try to provide a more complete answer.
Convert the image to grayscale. If we can't get an algorithm to work in grayscale, we'll inevitably run into problems with color. (See below)
[TBD] Do some preprocessing to reduce noise.
Find edge points using Sobel or (if you must) Canny.
Run Hough lines detection, but with a few caveats and parameterizations as described below.
Find the lines described a keystone-shaped quadrilateral. (This will likely be the inner quadrilateral of two: one inside the rail on the bed, and the other slightly larger quadrilateral at the cloth/wood rail edge at top.)
(Optional) Use the side pockets to help determine the orientation of the quadrilateral.
Use an affine transform to map the perspective-distorted table bed to a rectangle of [thankfully] known relative dimensions. We know the bed sizes in advance, so you can remap the distorted rectangle to a proper rectangle. (We'll ignore some optical effects for now.)
Remap the color image to the perspective-corrected rectangle. You'll probably need to tweak the positions of some balls.
General notes:
Filtering by color in the general sense can be difficult. It's tempting to think of the cloth as being simply green, blue, or red (or some other color), but when you look at the actual RGB values and try to separate colors you'll begin to appreciate what a nightmare working in color can be.
Optical distortion might throw off some edges.
The far short rail may be difficult to detect, BUT you do this: find the inside lines for the two long rails, then search vertically between the two rails for the first strong horizontal-ish edge at the far side of the image. That'll be the far short rail.
Although you probably want to use your phone camera for convenience, using a Kinect camera or similar (preferably smaller) device would make the problem easier. Not only would you have both color data and 3D data, but you would eliminate some problems with lighting since the depth data wouldn't depend on visible lighting.
For your app, consider limiting the search region for rail edges to a perspective-distorted rectangle. The user might be able to adjust the search region. This could greatly simplify the processing, and could help you work around problems if the table isn't lit well (as can be the case).
If color segmentation (as suggested by #Dima) works, get the outline of the blob using contour following. Then simplify the outline to a quadrilateral (or a polygon of few sides) by the Douglas-Peucker algorithm. You should find the four table edges this way.
For more accuracy, you can refine the edge location by local search of transitions across it and perform line fitting. Then intersect the lines to get the corners.
The following answer assumes you have already found the positions of the lines in the image. This however can be done "easily" by directly looking at the pixels and seeing if they are in a "line". Usually it is easier to detect this if the image has been deskewed first as well, i.e. Rotated so the rectangle (pool table) is more like this: [] than like /=/. Then it is just a case of scanning the pixels and if there are ones of similar colour alongside it assuming a line is between them.
The code works by looping over the lines found in the image. Whenever the end points of each line falls within a tolerance on within the x and y coordinates it is marked as a corner. Once the corners are found I take the average value between them to find where the corner lies. For example:
A horizontal line ending at 10, 10 and a vertical line starting at 12, 12 will be found to be a corner if there is a tolerance of 2 or more. The corner found will be at: 11, 11
NOTE: This is just to find Top Left corners but can easily be adapted to find all of them. The reason it has been done like this is because in the application where I use it, it is faster to sort each array first into an order where relevant values will be found first, see: Why is processing a sorted array faster than an unsorted array?.
Also note that my code finds the first corner for each line which might not be applicable for you, this is mainly for performance reasons. However the code can easily be adapted to find all the corners with all the lines then either select the "more likely" corner or average through them all.
Also note my answer is written in C#.
private IEnumerable<Point> FindTopLeftCorners(IEnumerable<Line> horizontalLines, IEnumerable<Line> verticalLines)
{
List<Point> TopLeftCorners = new List<Point>();
Line[] laHorizontalLines = horizontalLines.OrderBy(l => l.StartPoint.X).ThenBy(l => l.StartPoint.Y).ToArray();
Line[] laVerticalLines = verticalLines.OrderBy(l => l.StartPoint.X).ThenBy(l => l.StartPoint.Y).ToArray();
foreach (Line verticalLine in laVerticalLines)
{
foreach (Line horizontalLine in laHorizontalLines)
{
if (verticalLine.StartPoint.X <= (horizontalLine.StartPoint.X + _nCornerTolerance) && verticalLine.StartPoint.X >= (horizontalLine.StartPoint.X - _nCornerTolerance))
{
if (horizontalLine.StartPoint.Y <= (verticalLine.StartPoint.Y + _nCornerTolerance) && horizontalLine.StartPoint.Y >= (verticalLine.StartPoint.Y - _nCornerTolerance))
{
int nX = (verticalLine.StartPoint.X + horizontalLine.StartPoint.X) / 2;
int nY = (verticalLine.StartPoint.Y + horizontalLine.StartPoint.Y) / 2;
TopLeftCorners.Add(new Point(nX, nY));
break;
}
}
}
}
return TopLeftCorners;
}
Where Line is the following class:
public class Line
{
public Point StartPoint { get; private set; }
public Point EndPoint { get; private set; }
public Line(Point startPoint, Point endPoint)
{
this.StartPoint = startPoint;
this.EndPoint = endPoint;
}
}
And _nCornerTolerance is an int of a configurable amount.
A playing area of a pool table typically has a distinctive color, like green or blue. I would try a color-based segmentation approach first. The Color Thresholder app in MATLAB gives you an easy way to try different color spaces and thresholds.

XNA 4.0: How to remove text after drawn to screen?

Good day everyone.
I'm trying to draw the text "Pass Complete!" to screen with this code:
spriteBatch.DrawString(font, "PASS COMPLETE!", new Vector2(30, 130), Color.White);
Which does fire off the proper IF statement. However, how do I go about then removing that text from the screen? I'm really not sure at all where to go on from here and my instructor wants me to google the answer or find it in textbook. I have been all over my XNA textbook and I have found no outlet to removing that text.
Thanks for any and all help.
Update:
protected override void Draw(GameTime gameTime)
I have the IF statement included in here. Basically it checks collision with p_Receiver and if it the bool checks out, it draws the DrawString. Should I maybe be looking at this from a different angle?
Final:
I went ahead with the following as the answer and it's working better then before. :)
if (PassInfo == 3) {
(timer code)
(IF timer not "used up" then run the draw)
Working good for now.
I appreciate it.
I'm doing this by function that add text with some parameters into generic list. and then i update and draw items from that list. in pseudo code:
function addText(text,position,duration)
texts.add(new t(text,position,duration))
end function
function updateText()
for each t as text in texts.findall(where t.active)
t.duration -= 1
if t.duration < 0 then t.active = false
next
end function
function drawText()
for each t as text in texts.findall(where t.active)
//draw it
next
end function
so by this you can add unlimited number of texts on different position and duration on screen.
A lot of games redraw the entire window / screen each time through the draw cycle so there's a distinct chance that the solution to removing it is simply to stop drawing it.
i.e. have your if condition not draw the text when it is no longer required.
If, on the other hand, you've some more complex drawing logic that only draws portions of the window / screen that need updating then you'll need to include logic to redraw that part of the screen that contained the text once it is no longer needed.

Equivalent to CGRectIntersectsRect

Is there an equivalent to CGRectIntersectsRect that would be something more along the lines of points intersecting... I'm making a game and RectIntersectsRect works for what I want it to do but it looks bad because sometimes the corner of the one object will intersect the corner of the other and it will call the method, and you can barely see that the two objects touched, so it looks like it just glitches. Is there a CGPointIntersectsPoint or something along the lines of that? Thanks.
You can use CGRectContainsPoint to see if one of your rectangle contains a corner of the other, but you will get the same issue.
You can look for the intersection of the two rectangles using CGRectIntersection. It will give you an other CGRect, which represents the area in common from your two rectangles. From this rectangle, you can check width and height to see if the intersection is "big enough"
CGRect intersection = CGRectIntersection(rect1, rect2);
if (CGRectGetWidth(intersection) > kHorizontalThreshold || CGRectGetHeight (intersection) > kVerticalThreshold)
{
// call your intersection method here
}
Try CGRectContainsPoint. If you want to just compare two points use CGPointEqualToPoint.
You can't really have a point intersecting another point as they're two exact points in space. The only way they can "intersect" is by being equal.

Resources