I have user input that consists of a drawn rectangle (freestyle). Now this drawn figure isn't perfect, so I would like to redraw the shape for them based on an algorithm.
I have a bunch of coordinates from the user's drawing. I would like to find the greatest (x,y) and the lowest (x,y) coordinates and use the distance between those to determine the diagonal of the rectangle.
But I'm having difficulty determining the greatest (x,y) coordinate and the lowest (x,y) coordinate.
I can't take the greatest y with the greatest x, or the greatest x with the greatest y for example because maybe the user just made an accidental jut out in their line. (Does that make sense?)
Pretend below is a user drawn line.. if i used the greatest y with the greatest x, I would not have the desired coordinate (because it would find the coordinate in the accidental jut out)
----
/ \
----/ \-------- ----- --
--------------/ \---------------/ \------/ \--
Hope you understand what I'm getting at..
I guess another way of putting it is that I would like the coordinate closest to (0,0) and if my canvas was 1000 x 1000, I would like the second coordinate to be closest to (1000,1000). (the two extreme coordinates)
Can anyone help with this algorithm?
Thanks in advance!
Depending on how well you want the algorithm-generated rectangle to fit the user input, you might try the following:
Average all x and y coordinates to give you the center of your rectangle, (Xc, Yc).
Find your highest and lowest x value, subtract the lowest from the highest and divide by two. Repeat for the y values. Let us call these Xs and Ys (s is for 'side').
The important corners (upper left and lower right) would then become (Xc - Xs, Yc - Ys) and (Xc + Xs, Yc + Ys).
Draw lines as appropriate.
Now, this will give you a bounding-box wherein all user given points are contained. If you are looking for more of a best-fit type algorithm, replace the (max - min) / 2 function in step two with an averaging function. A simple one might involve averaging only points to one side of the center point (either above / below or left / right) and using those as offsets from center. Note that this will give you four offsets, only two of which you will use at any given time.
The rough idea presented here can be tuned to taste, depending on what kind of user input you are expecting (e.g. how distorted you expect it might be). Further improvements can be made using linear regression lines, assuming you are able to distinguish sides either via the points themselves or by user input methods (ex. drawing each side of the rectangle with a discrete action rather than all at once).
Hope this quick example will point you in the right direction.
if you want to find the closest point to (0,0), then just find it!
point FindClosestToOrigin(point[] P)
{
point closest = P[0];
foreach(point p in P)
{
if (DistanceOriginS(p) < DistanceOriginS(closest)) closest = p;
}
return closest;
}
float DistanceOriginS(point p)
{
return p.x*p.x + p.y*p.y;
}
you can easily modify the algo to find points closest to the rest of screen edges.
Just do an average over all points and use it as the position of rectangle sides.. of course this assumes you are able to distinguish the four sides of the rectangle otherwise you could try a way to split the coordinates into 4 sides (by checking the horizontal and vertical variation with some threshold) and then compute the average for each side and adjust it to link sides.
Related
I'm looking for an appropriate algorithm that reliably predicts input coordinates given by a digital stylus (e.g. Surface Pen). In my application, I'm given the coordinates of the input as x and y coordinates on the screen (together with their timestamps).
Given a list of events ordered chronologically, my aim is to find the coordinate of the "next" events.
The simple algorithm I came up with is using weighted average. Here is some code that illustrates it (in real code I use more than just 4 points):
class Point{
double x;
double y;
double timestamp;
}
// this contains 4 points
// in chronological order
vector<Point> points;
// predict using simple weighted average
// the subtraction operation is simply subtraction on x and y coordinates
Point diff1 = points[1]-points[0];
Point diff2 = points[2]-points[1];
Point diff3 = points[3]-points[2];
// add a weighted difference to the last point we have
Point predictedPoint = points[3] + diff1 * 0.2 + diff2 * 0.3 + diff3 * 0.5;
This doesn't work as well as I would like to as often the predicted input is not very accurate. So I would like to find something better that estimates the next input based on previous points (it'd be nice if this accounted for the velocity of inputs as well).
Unfortunately not a go to answer but merely some solution directions to consider.
One option is to plot the coordinates as a function of time and calculate the trendline (see e.g. https://math.stackexchange.com/questions/204020/what-is-the-equation-used-to-calculate-a-linear-trendline)
In your case the X axis would be the time component and the Y axis either the X or Y coordinate, so you'll end up with 2 functions. Take T=0 for the first timespan and the rest of the X axis in seconds.
This solution will only work with somewhat linear movements (maybe a zigzag) only. The issue with this approach however is that when let's say you draw half a circle the next predicted point will try to make an S curve because you average only known points.
Another option would be to differentiate the slope. Lets say you want to draw a hexagon, then the slope of your first line will be 0deg, second line 60deg, 3rd line 120deg, 4th 180deg, 5th 270deg, 6th=1St 360=0deg. In this case your X,Y coordinates go all over the place but the difference in slope is every time 60deg. Same applies to drawing a circle but the steps are infinitely smaller (this is actually one of the methods to calculate pi)
Now if you would just calculate the slope over the actual X,Y coordinates you'll basically end up with the same kind of algorithm as in your initial code. Basically you want to calculate the acceleration (using same method as described in the beginning of this answer), see e.g. https://blog.prepscholar.com/acceleration-formula-equation, and then calculate the trendline over the acceleration.
But also this solution is not fool proof. If your pencil trace is a zigzag then both your direction and acceleration will go nuts on every corner and your prediction will make no sense.
My advice would be to record a number of strokes, plot the result in a number of graphs and try some different formula's and methods to see which gives the best result.
I have a circle I want to divide up in to a number of segments all defined by X and Y coordinates. How to I test to see if a point (X, Y) is in a particular segment?
A code example would be preferable.
You don't need to use trigonometry for this (and in general, trigonometry should be avoided whenever possible... it leads to too many precision, domain, and around-the-corner problems).
To determine whether a point P is counter-clockwise of another point A (in the sense of being in the half-plane defined by the left side of a directed line going through the origin and then through A), you can examine the sign of the result of Ax*Py - Ay*Px. This is generally known as the "perpendicular dot product", and is the same as the Z coordinate of the 3D cross product.
If there are two points A and B (with B defining the CCW-most extent) defining a sector, and the sector is less than half the circle, any point which is CCW of A and CW of B can be classified as in that sector.
That leaves only a sector which is more than half of the circle. Obviously, a given set of points can only define at most one such sector. There's clever things you can do with angle bisection, but the easiest approach is probably just to classify points as in that sector if you can't classify them as being in any other sector.
Oh, forgot to mention -- determining the order of the points for the purposes of pairing them up for sectors. Not to go against my previous advice, but the most straightforward thing here is just to sort them by their atan2 (not atan... never ever use atan).
Use the polar coordinate system centred at the centre of the circle, and examine the angular coordinate (φ in the Wikipedia article).
What exactly you do with φ depends on how your segments are defined. For example, if you have n equal segments that start at 0 radians, floor(φ * n / (2 * π)) will give you the segment number.
Your segment is defined by two intersections between the circle and a line. You just have to know if:
The angle between the center of your circle and your point is between
the angles formed by the two previous points and the center.
the point is in the circle (the length from this point to the center is smaller than the radius)
from what side is the point compared to the line (it must be beyond the line).
Remark
In geometry, a circular segment (symbol: ⌓) is a region of a circle
which is "cut off" from the rest of the circle by a secant or a chord.
Here is a segment:
If x & y are not already relative to the center of the circle, subtract the coordinates of the center of the circle:
x -= circle.x
y -= circle.y
Use atan2 to get the angle of the point about the origin of the circle:
angle = atan2(y, x)
This angle is negative for points below the x-axis, so adjust to always be positive:
if (angle < 0) angle += 2 * pi
Assuming your segments are equally spaced, use this formula to get the index of the segment:
segment = floor((angle * numSegments) / (2 * pi))
If you find the result is referring to a segment on the opposite side of the circle to what you want, you might have to do y = -y in the beginning or a segment = (numSegments - 1) - segment at the end to flip it round the right way, but it should basically work.
Input: a set of rectangles within the area (0, 0) to (1600, 1200).
Output: a point which none of the rectangles contains.
What's an efficient algorithm for this? The only two I can currently think of are:
Create a 1600x1200 array of booleans. Iterate through the area of each rectangle, marking those bits as True. Iterate at the end and find a False bit. Problem is that it wastes memory and can be slow.
Iterate randomly through points. For each point, iterate through the rectangles and see if any of them contain the point. Return the first point that none of the rectangles contain. Problem is that it is really slow for densely populated problem instances.
Why am I doing this? It's not for homework or for a programming competition, although I think that a more complicated version of this question was asked at one (each rectangle had a 'color', and you had to output the color of a few points they gave you). I'm just trying to programmatically disable the second monitor on Windows, and I'm running into problems with a more sane approach. So my goal is to find an unoccupied spot on the desktop, then simulate a right-click, then simulate all the clicks necessary to disable it from the display properties window.
For each rectangle, create a list of runs along the horizontal direction. For example a rectangle of 100x50 will generate 50 runs of 100. Write these with their left-most X coordinate and Y coordinate to a list or map.
Sort the list, Y first then X.
Go through the list. Overlapping runs should be adjacent, so you can merge them.
When you find the first run that doesn't stretch across the whole screen, you're done.
I would allocate an image with my favorite graphics library, and let it do rectangle drawing.
You can try a low res version first (scale down a factor 8), that will work if there is at least a 15x15 area. If it fails, you can try a high res.
Use Windows HRGNs (Region in .net). They were kind of invented for this. But that's not language agnostic no.
Finally you can do rectangle subtraction. Only problem is that you can get up to 4 rectangles each time you subtract one rect from another. If there are lots of small ones, this can get out of hand.
P.S.: Consider optimizing for maximized windows. Then you can tell there are no pixels visible without hit testing.
Sort all X-coordinates (start and ends of rectangles), plus 0 & 1600, remove duplicates. Denote this Xi (0 <= i <= n).
Sort all Y-coordinates (start and ends of rectangles), plus 0 & 1200, remove duplicates. Denote this Yj (0 <= j <= m).
Make a n * m grid with the given Xi and Yj from the previous points, this should be much smaller than the original 1600x1200 one (unless you have a thousand rectangles, in which case this idea doesn't apply). Each point in this grid maps to a rectangle in the original 1600 x 1200 image.
Paint rectangles in this grid: find the coordinates of the rectangles in the sets from the first steps, paint in the grid. Each rectangle will be on the form (Xi1, Yj1, Xi2, Yj2), so you paint in the small grid all points (x, y) such that i1 <= x < i2 && j1 <= y < j2.
Find the first unpainted cell in the grid, take any point from it, the center for example.
Note: Rectangles are assumed to be on the form: (x1, y1, x2, y2), representing all points (x, y) such that x1 <= x < x2 && y1 <= y < y2.
Nore2: The sets of Xi & Yj may be stored in a sorted array or tree for O(log n) access. If the number of rectangles is big.
If you know the minimum x and y dimensions of the rectangles, you can use the first approach (a 2D array of booleans) using fewer pixels.
Take into account that 1600x1200 is less than 2M pixels. Is that really so much memory? If you use a bitvector, you only need 235k.
You first idea is not so bad... you should just change the representation of the data.
You may be interessed in a sparse array of booleans.
A language dependant solution is to use the Area (Java).
If I had to do this myself, I'd probably go for the 2d array of booleans (particularly downscaled as jdv suggests, or using accelerated graphics routines) or the random point approach.
If you really wanted to do a more clever approach, though, you can just consider rectangles. Start with a rectangle with corners (0,0),(1600,1200) = (lx,ly),(rx,ry) and "subtract" the first window (wx1,wy1)(wx2,wy2).
This can generate at most 4 new "still available" rectangles if it is completely contained within the original free rectangle: (eg, all 4 corners of the new window are contained within the old one) they are (lx,ly)-(rx,wy1), (lx,wy1)-(wx1,wy2), (wx2,wy1)-(rx,wy2), and (lx,wy2)-(rx,ry). If just a corner of the window overlaps (only 1 corner is inside the free rectangle), it breaks it into two new rectangles; if a side (2 corners) juts in it breaks it into 3; and if there's no overlap, nothing changes. (If they're all axes aligned, you can't have 3 corners inside).
So then keep looping through the windows, testing for intersection and sub-dividing rectangles, until you have a list (if any) of all remaining free space in terms of rectangles.
This is probably going to be slower than any of the graphics-library powered approaches above, but it'd be more fun to write :)
Keep a list of rectangles that represent uncovered space. Initialize it to the entire area.
For each of the given rectangles
For each rectangle in uncovered space
If they intersect, divide the uncovered space into smaller rectangles around the covering rectangle, and add the smaller rectangles (if any) to your list of uncovered ones.
If your list of uncovered space still has any entries, they contain all points not covered by the given rectangles.
This doesn't depend on the number of pixels in your area, so it will work for large (or infinite) resolution. Each new rectangle in the uncovered list will have corners at unique intersections of pairs of other rectangles, so there will be at most O(n^2) in the list, giving a total runtime of O(n^3). You can make it more efficient by keeping your list of uncovered rectangles an a better structure to check each covering rectangle against.
This is a simple solution with a 1600+1200 space complexity only, it is similar in concept to creating a 1600x1200 matrix but without using a whole matrix:
Start with two boolean arrays W[1600] and H[1200] set to true.
Then for each visible window rectangle with coordinate ranges w1..w2 and h1..h2, mark W[w1..w2] and H[h1..h2] to false.
To check if a point with coordinates (w, h) falls in an empty space just check that
(W[w] && H[h]) == true
I need to initialize some three dimensional points, and I want them to be equally spaced throughout a cube. Are there any creative ways to do this?
I am using an iterative Expectation Maximization algorithm and I want my initial vectors to "span" the space evenly.
For example, suppose I have eight points that I want to space equally in a cube sized 1x1x1. I would want the points at the corners of a cube with a side length of 0.333, centered within the larger cube.
A 2D example is below. Notice that the red points are equidistant from eachother and the edges. I want the same for 3D.
In cases where the number of points does not have an integer cube root, I am fine with leaving some "gaps" in the arrangement.
Currently I am taking the cube root of the number of points and using that to calculate the number of points and the desired distance between them. Then I iterate through the points and increment the X, Y and Z coordinates (staggered so that Y doesn't increment until X loops back to 0, same for Z with regard for Y).
If there's an easy way to do this in MATLAB, I'd gladly use it.
The sampling strategy you are proposing is known as a Sukharev grid, which is the optimal low dispersion sampling strategy, http://planning.cs.uiuc.edu/node204.html. In cases where the number of samples is not n^3, the selection of which points to omit from the grid is unimportant from a sampling standpoint.
In practice, it's possible to use low discrepancy (quasi-random) sampling techniques to achieve very good results in three dimensions, http://planning.cs.uiuc.edu/node210.html. You might want to look at using Halton and Hammersley sequences.
http://en.wikipedia.org/wiki/Halton_sequence
http://en.wikipedia.org/wiki/Constructions_of_low-discrepancy_sequences
You'll have to define the problem in more detail for the cases where the number of points isn't a perfect cube. Hovever, for the cases where the number of points is a cube, you can use:
l=linspace(0,1,n+2);
x=l(2:n+1); y=x; z=x;
[X, Y, Z] = meshgrid(x, y, z);
Then for each position in the matrices, the coordinates of that point are given by the corresponding elements of X, Y, and Z. If you want the points listed in a single matrix, such that each row represents a point, with the three columns for x, y, and z coordinates, then you can say:
points(:,1) = reshape(X, [], 1);
points(:,2) = reshape(Y, [], 1);
points(:,3) = reshape(Z, [], 1);
You now have a list of n^3 points on a grid throughout the unit cube, excluding the boundaries. As others have suggested, you can probably randomly remove some of the points if you want fewer points. This would be easy to do, by using randi([0 n^3], a, 1) to generate a indices of points to remove. (Don't forget to check for duplicates in the matrix returned by randi(), otherwise you might not delete enough points.)
This looks related to sphere packing.
Choose the points randomly within the cube, and then compute vectors to the nearest neighbor or wall. Then, extend the endpoints of the smallest vector by exponentially decaying step size. If you do this iteratively, the points should converge to the optimal solution. This even works if the number of points is not cubic.
a good random generator could be a first a usable first approximation. maybe with a later filter to reposition (again randomly) the worst offenders.
I have a list of two-dimensional points and I want to obtain which of them fall within a semi-circle.
Originally, the target shape was a rectangle aligned with the x and y axis. So the current algorithm sorts the pairs by their X coord and binary searches to the first one that could fall within the rectangle. Then it iterates over each point sequentially. It stops when it hits one that is beyond both the X and Y upper-bound of the target rectangle.
This does not work for a semi-circle as you cannot determine an effective upper/lower x and y bounds for it. The semi-circle can have any orientation.
Worst case, I will find the least value of a dimension (say x) in the semi-circle, binary search to the first point which is beyond it and then sequentially test the points until I get beyond the upper bound of that dimension. Basically testing an entire band's worth of points on the grid. The problem being this will end up checking many points which are not within the bounds.
Checking whether a point is inside or outside a semi-circle (or a rectangle for that matter) is a constant-time operation.
Checking N points lie inside or outside a semi-circle or rectangle is O(N).
Sorting your N points is O(N*lg(N)).
It is asymptotically faster to test all points sequentially than it is to sort and then do a fast culling of the points based on a binary search.
This may be one of those times where what seems fast and what is fast are two different things.
EDIT
There's also a dead-simple way to test containment of a point in the semi-circle without mucking about with rotations, transformations, and the like.
Represent the semi-circle as two components:
a line segment from point a to b representing the diameter of the semi-circle
an orientation of either left-of or right-of indicating that the semi-circle is either to the left or right of line segment ab when traveling from a to b
You can exploit the right-hand rule to determine if the point is inside the semicircle.
Then some pseudo-code to test if point p is in the semi-circle like:
procedure bool is_inside:
radius = distance(a,b)/2
center_pt = (a+b)/2
vec1 = b - center_pt
vec2 = p - center_pt
prod = cross_product(vec1,vec2)
if orientation == 'left-of'
return prod.z >= 0 && distance(center_pt,p) <= radius
else
return prod.z <= 0 && distance(center_pt,p) <= radius
This method has the added benefit of not using any trig functions and you can eliminate all square-roots by comparing to the squared distance. You can also speed it up by caching the 'vec1' computation, the radius computation, center_pt computation, and reorder a couple of the operations to bail early. But I was trying to go for clarity.
The 'cross_product' returns an (x,y,z) value. It checks if the z-component is positive or negative. This can also be sped up by not using a true cross product and only calculating the z-component.
First, translate & rotate the semi-circle so that one end is on the negative X-axis, and the other end is on the positive X-axis, centered on the origin (of course, you won't actually translate & rotate it, you'll just get the appropriate numbers that would translate & rotate it, and use them in the next step).
Then, you can treat it like a circle, ignoring all negative y-values, and just test using the square root of the sum of the squares of X & Y, and see if it's less than or equal to the radius.
"Maybe they can brute force it since they have a full GPU dedicated to them."
If you have a GPU at your disposal, then there are more ways to do it. For example, using a stencil buffer:
clear the stencil buffer and set the stencil operation to increment
render your semicircle to the stencil buffer
render your points
read back the pixels and check the values at your points
the points that are inside the semicircle would have been incremented twice.
This article describes how stencil buffers can be used in OpenGL.
If there's a standard algorithm for doing this, I'm sure someone else will come up with it, but if not: you could try sorting the points by distance from the center of the circle and iterating over only those whose distance is less than the semicircle's radius. Or if computing distance is expensive, I'd just try finding the bounding box of the semicircle (or even the bounding square of the circle of which the semicircle is part) and iterating over the points in that range. To some extent it depends on the distribution of the points, i.e. do you expect most of them or only a small fraction of them to fall within the semicircle?
You can find points in a circle and points on one side of a given slope, right?
Just combine the two.
Here's part of a function I wrote do get a cone firing arc for a weapon in a tile based game.
float lineLength;
float lineAngle;
for(int i = centerX - maxRange; i < centerX + maxRange + 1; i++){
if(i < 0){
continue;
}
for(int j = centerY - maxRange; j < centerY + maxRange + 1; j++){
if(j < 0){
continue;
}
lineLength = sqrt( (float)((centerX - i)*(centerX - i)) + (float)((centerY - j)*(centerY - j)));
lineAngle = lineAngles(centerX, centerY, forwardX, forwardY, centerX, centerY, i, j);
if(lineLength < (float)maxRange){
if(lineAngle < arcAngle){
if( (float)minRange <= lineLength){
AddToHighlightedTiles(i,j);
}
}
}
}
}
The variables should be self explanatory and the line angles function takes 2 lines and finds the angle between them. The forwardX and forwardY is just one tile in the correct direction from the center X and Y based on what angle you're pointing in. Those can be gotten easily with a switch statement.
float lineAngles(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4){
int a = x2 - x1;
int b = y2 - y1;
int c = x4 - x3;
int d = y4 - y3;
float ohSnap = ( (a * c) + (b * d) )/(sqrt((float)a*a + b*b) * sqrt((float)c*c + d*d) );
return acos(ohSnap) * 180 / 3.1415926545f;
}
It would appear that a simple scheme will work here.
Reduce the number of points in the set, by first computing the convex hull. Only the points on the convex hull will contribute to any interaction with any convex bounding shape. So retain only the subset of points on the perimeter of the hull.
It can easily be argued that the minimal radius bounding semi-circle must have one edge (two points) of the convex hull coincident along the diameter of the semi-circle. I.e., if some edge of the hull does not lie in the diameter, then there exists a different semi-circle with smaller diameter that contains the same set of points.
Test each edge in sequence. (A convex hull often has relatively few edges, so this will go quickly.) Now it becomes a simple 1-d minimization problem. If we choose to assume the edge in question lies on the diameter, then we merely need to find the center of the sphere. It must lie along the current line which we are considering to be the diameter. So as a function of the position of the point along the current diameter, just find the point which lies farthest away from the nominal center. By minimizing that distance, we find the radius of the minimal semi-circle along that line as a diameter.
Now, just choose the best of the possible semi-circles found over all edges of the convex hull.
If your points have integer co-ordinates, the fastest solution may be a lookup table. Since a semicircle is convex, for each y co-ordinate, you get a fixed range of x, so each entry in your lookup table gives maximum and minimum X co-ordinates.
Of course you still need to precalculate the table, and if your semicircle isn't fixed, you may be doing that a lot. That said, this is basically one part of what would once have been done to render a semicircle - the full shape would be rendered as a series of horizontal spans by repeatedly calling a horizontal line drawing function.
To calculate the spans in the first place (if you need to do it repeatedly), you'd probably want to look for an old copy of Michael Abrash's Zen of Graphics Programming. That described Bresenhams well-known line algorithm, and the not-so-well-known Hardenburghs circle algorithm. It shouldn't be too hard to combine the span-oriented versions of the two to quickly calculate the spans for a semi-circle.
IIRC, Hardenburgh uses the x^2 + y^2 = radius^2, but exploits the fact that you're stepping through spans to avoid calculating square roots - I think it uses the fact that (x+1)^2 = x^2 + 2x + 1 and (y-1)^2 = y^2 - 2y + 1, maintaining running values for x, y, x^2 and (radius^2 - y^2), so each step only requires a comparison (is the current x^2 + y^2 too big) and a few additions. It's done for one octant only (the only way to ensure single-pixel steps), and extended to the full circle through symmetry.
Once you have the spans for the full circle, it should be easy to use Bresenhams to cut off the half you don't want.
Of course you'd only do all this if you're absolutely certain that you need to (and that you can work with integers). Otherwise stick with stbuton.
translate the center of the arc to the origin
compute angle between ordinate axis and end points of radii of semi-cirlce
translate the point in question by same dx,dy
compute distance from origin to translated x,y of point, if d > radius of circle/arc eliminate
compute angle between ordinate axis and end point
if angle is not between starting and ending arc of semi-cirlce, eliminate
points remaning should be inside semi-circle
I guess someone found the same solution as me here but I have no code to show as its pretty far in my memory...
I'd do it by steps...
1. I'd look if i'm within a circle... if yes look on which side of the circle.
2. By drawing a normal vector that come from the vector made by the semi-sphere. I could know if I'm behind or in front of the vector...and if you know which side is the semi sphere and which side is the void...It will be pretty damn easy to find if you're within the semi sphere. You have to do the dot product.
I'm not sure if it's clear enough but the test shouldn't be that hard to do...In the end you have to look for a negative or positive value...if it's 0 you're on the vector of the semisphere so it's up to you to say if it's outside or inside the semi-sphere.
The fastest way to do this will depend on your typical data. If you have real-world data to look at, do that first. When points are outside the semi-circle, is it usually because they are outside the circle? Are your semi-circles typically thin pie slices?
There are several ways to do this with vectors. You can scale the circle to a unit circle and use cross-products and look at the resultant vectors. You can use dot-products and see how the prospective point lands on the other vectors.
If you want something really easy to understand, first check to make sure it's inside the circle, then get the angle and make sure it's between the angle of the two vectors that dictate the semi-circle.
Edit: I had forgotten that a semicircle is always half a circle. I was thinking of any arbitrary section of a circle.
Now that I have remembered what a semicircle is, here's how I would do that. It's similar to stbuton's solution, but it represents the semicircle differently.
I'd represent the semicircle as the unit vector that bisects the semicircle. You can easily get that from either one of the vectors that indicate the boundary of the semicircle (because they are 90 degrees away from the representation) by swapping x and y and negating one of them.
Now you just cross the vector created by subtracting the point to be tested from the circle's center. The sign of z tells you whether the point is in the semicircle, and the length of z can be compared against the radius.
I did all the physics for Cool Pool (from Sierra Online). It's all done in vectors and it's filled with dots and crosses. Vectors solutions are fast. Cool Pool was able to run on a P60, and did reasonable breaks and even spin.
Note: For solutions where you're checking sqrt(xx+yy), don't even do the sqrt. Instead, keep the square of the radius around and compare against that.