I have 2 sets of parallel and when their angles differ, I end up with a intersection on one end, and an open gap on the other. I have taken care of the interesection, by setting the endPoint of line1 to the same as the starting point for line2. Like so...
This is the code I have so far for adding the lines....
for (int i: 0; i < myLines.size() ; i++) {
Line myLine = checkforInterection( myLines, i);
myCanvas.Children.Add(myLine);
myCanvas.Children.Add(createParallel(myLine));
}
I would like to close the gap on the rightHand side by having a curved line that can span the distance. What is the best way of going about this?
Use a BezierSegment to obtain a smooth curve. The start and end points should be the start and end points of the straight line. The control point may require some experimentation to get looking like you want it to, since that's more of a preference, but setting the control point to the projected intersection of the two lines the curve is attached to would make a good starting point. If you do want to tweak it after that, you should move it along the line from the projected intersection to the actual intersection of the two lines on the left.
For clarity:
Start off with the start and end points at the green dots. Start off with the control point at the intersection of the red line, and, if you want to adjust it, move it along the blue line to keep a symmetric curve.
Note: using the intersection of the red lines will give you a perfectly smooth transition; other points won't.
Related
I'm still making the game about tower building using Unity and now I have problem that have haunted me for about week now.
Game mechanic for losing is that there is line which goes up at a certain speed and when it goes above the tower, game should end. I'm wondering is there any way of checking highest objects highest point(because of rotated objects and irregularly stacked objects)?
There's a few ways to achieve this:
1) You can shoot a bunch of rays down from high up in the sky. Find all the hit.point positions and then loop through the points and store which building is the highest.
2) Another would be for each block of your building that is added - keep it as a child of an Empty Building gameObject. Then all you need to do is see which Building gameObject has the most children and you know it's the tallest. This assumes all blocks are the same size in Y and then you can easily calculate the height with highestChildCount * blockSizeY
3) Another way to do it would be to use the point in the line that is traveling up. Shoot a ray out of that point to the left and right. If it is hitting a building then the game continues. If it doesn't hit anything the game is over. This is the simpliest as it doesn't require calculation of any heights and your buildings can be made any way you like as long as they have colliders on it for the ray to hit. <--- This is likely the best method for what I'm hearing you asking.
(Note. I might have some spelling mistakes in the naming of methods so proofread before copy-pasting)
Since your are using a line, you might want to find the bounding box of an object. I have never tried the bounding box method so it might not work. The second method uses a little bit of math. If your line is vertical, then finding the highest point is easy. All you need to do is find the y position of the object and add half the y-scale to find the highest point. Note it will only work if the transform origin of the object is at the center. If the origin is at the bottom of the line you will have to add the full y-scale value. If its one third the way up, then only 2 thirds the y-scale value. I think you get the idea. This rule apples for the next condition too. If your line is at an angle, this is where it gets a little bit more complicated. We need to find the absolute value of the rotation in which the line is rotated at. Make sure the line is rotated at less than a 90 degree angle from being vertical. After this, we need to know the length of the line. Imagine a right triangle that the line itself is the hypotenuse, the base is the distance between the farthest left point of the line to the farthest right on the line(or other way around), and the distance from the lowest point of the line to the highest point of the line being the actual height of the triangle. Since we know the angle the line is rotated at and the length of the line, we need to figure out the ratio between the side opposite to the angle that represents the rotation the the hypotenuse(aka the length of the line) and the hypotenuse. This always stays the same if the rotation is the same for all right triangles. Because of this why use mathf.sin(), the rotation of the line. Remember to convert the rotation value(which is stored in degrees) to radians. This can be done by multiplying the rotation value by mathf.deg2rad. Once we know the sin, we multiply the length by the sin value that is outputted. Now we know how long the distance from the bottom to the top of the line is. Again, if the origin is the middle we add the y-position to half the value we get from the previous calculations. If it is in the bottom then the y-position plus the whole value we get from the previous calculations. Same rule as before. I am also quite new to Unity, only a little over a year of experience so there may be fallacies in my answer. Hope it helps. :)
I am trying to create a 2(or more) circles from a list of edgepoints which is sorted. A egdepoint is just a point. A list of edgepoints make the edge of a circle. Drawing a line between the edgepoints gives the black line in the pictures. So there is no radius and circles can vary in size.
It looks like this:
My idea is to split it like picture 2. Next, create circles like in this article. Ofcourse with the fist, middle and last point.
I created a method to detect whether the edgepoints are sorted clockwise or counter clockwise. Unfortunately I am stuck on how to detect these "split points" The picture can be rotated ofcourse.
The result should be 2(or more) list with edgepoints:
So how can I detect these "split points"? Or is there a better way to detect intersecting circles as separate?
Input: Something like Point[]. Output: Something like List[Circle]
Assume input is sorted by position around the outer edge of some picture that is made up of overlapping circles. Any points in the interior of the picture are not included.
I thought about it more and I think you can find the points easier if you consider slope. Points where the slope varies wildly are the points you are looking for.
[Revised thought - Find the transition points first, then the circles.]
Start by using a function to calculate the slope of a line segment between two points. As you go around a circle, you will have a reasonable change in slope (you will have to discover this by reviewing how close the points are together). Say you have points like { A, B, C, D, ...}. Compute the slope of A->B and B->C. If the points are evenly spaced, that difference or the average difference might be a tolerance (you have to be careful of transition points here - maybe compute an average over the entire set of points). If at some point the slope of K->L and L->M is very different from J->K and K->L then record that index as a transition point. Once you have traversed the whole set (include a test for Y->Z and Z->A as well if it is a closed shape), the recorded indexes should define the transition points. Use the mid-point of each segment as the third point for each circle. (e.g. if you identified I and M as transition points, then use I, K, and M to define a circle).
[Original thought - find the circles first]
Use the referenced article to determine the center of a circle based on three points. Then determine if it is really an interesting circle by testing some of the points around the reference points. (Say, pick every 5th or 10th point then verify with all the interior points). With more overlapping circles, this becomes a less effective process so you will have to define the algorithm carefully. Once you get all the reference circles, process through all of the edge points (assuming these are points on the exterior of the drawing). Using center, radius, a distance formula, and a tolerance, determine which points are on which circle. Points that fit the tolerance on more than one circle are the points you are looking for I think.
I got a problem to solve. Look at the picture:
Image.
Red filled Ellipse is an obstacle.
Black dots are beginning and end of "road".
Blue line, is shortest way from one point to another.
I draw obstacles using mouse (mouse click creates ellipse), then i put in cords of start and the end, and then i use DrawLine to draw line from point to point. The question here is, how can i check or count, how many pixels of line, goes trough obstacle?
I thought of putting every pixel color in a 2D array before drawing the line, and then check it somehow on the numbers, counting shortest way from point to point, and checking how many 255's (obstacle number) would it meet in that array? As you see, i can create obstacle that way, so line will go trough the middle, just some part of it, or even next to it. I am simply lacking any idea how to do that. I need it, so i could rate every "road". More it goes trough obstacle, the less rate it gets.
Any ideas? Any algorithm?
Using the equations of the ellipse and the line, find the intersection points of the line with the outline of the ellipse (there may be 2, 1 or no intersections). You can find a worked example of this here.
If there are indeed 2 intersection points, use the distance formula to calculate the distance between them.
Is there anyway that allows me to find all the intersection points between a line and a grid? ( The intersection circles are not drawn to scale with each other, I know)
A brute force way is to compute very intersection for the x-y grid with the line, but this algorithm is awfully inefficient (O(m*n), where m is the number of x grid and n is the number of y grid).
I'm looking for a better algorithm on this.
Sounds like you need a Digital Differential Analyzer or Bresenham's line algorithm. Bresenham is the same algorithm used to draw lines on a bitmap; in this case, coloring a pixel is equivalent to checking for collisions in that square.
I'm not sure I really understand the question. Is this what you're looking for by any chance?
If the grid is axis aligned:
find out the line equation
calculate the intersection points
directly using either the grid
line's x or y as a fixed variable
If the grid is regular, the distance between the intersections with each horizontal line will be the same. The same also goes for the vertical lines. You could just do a simple iterative algorithm with dx and dy in that case.
Algorithm:
The grid consists out of walls.
A wall is of/in a certain dimension: (Vertical, Horizontal, Depth)
The wall dimensions intersect forming cells (in final dimension)
The line intersects the walls primarly in their own dimension.
The solution is to view the problem as: How to intersect a line with a wall in it's own dimension.
The solution is to slide across the line from wall to wall, switch dimensions as necessary.
The sliding across the line happens such that the nearest wall is always chosen as the next destination.
The sliding from wall to wall in it's own dimension is constant/always the same.
The intersection of the line and the walls is different per dimension.
This ultimately decides the order of the wall intersections.
The solution is therefore to:
Phase 1: Initialization
Compute Dimension.IntersectT
Compute Dimension.SlideT
Phase 2: Start sliding from origin towards destination selecting nearest wall:
Dimension.T := Dimension.IntersectT
while ? end condition ?
Select smallest Dimension.T
Update selected Dimension.T += Dimension.SlideT
end
The difficulty lies in computing the Ts.
Bye,
Skybuck.
I have some problems getting an algorithm for my game to work and hope someone here can help me. Google didn't seem to be a good help as most solutions just work for full tiles.
In the game units can occupy different positions inside a tile, i.e. they can be in the upper left corner, center, bottom right, ... position of tile (2/3), i.e. (2.2/3.1), (2.5/3.5), (2.8/3.9).
If they move from position (2.2/3.1) to (5.7/4.1) i require a check to see if there is an obstacle in the path.
My current algorithm is:
Starting from (2.2/3.1)
Calculate the angle of the movement (i.e. 70 degree)
Move 0.1 steps in that direction
Check which tile i'm on (floor(p.X)/floor(p.Y))
Repeat from 2
This algorithm works but to me it doesn't look very efficient as an obstacle can be only a full tile, not a part of a tile (units don't collide). If i increase the step size i begin to miss tiles that are only crossed slightly (i.e. you only cross the lowest left corner). Even with a step size of 0.1 it's still possible to miss an obstacle.
I tried to find a solution to take the sub map (all tiles with the corners (floor(start.X)/floor(start.Y)) and (ceil(start.X)/ceil(start.Y)), move through every tile and check mathmatically if it gets crossed. Sadly i seem to lack the required math knowledge for this check.
My last idea was to take all 4 borders of a tile as a line and do line-intersection but that seems to be slower than my original approach.
Any hints?
Thanks.
Instead of tracing the path by stepping along the line - you want to jump right to the next possible tile (the border). This can be calculated fairly simply. I will use your sample numbers above.
Calculate the line eqn (y= .286x + 2.471)
You are starting on tile 2,3 and moving towards tile 5,4. So calculate the y value when x goes to 3 (the border to the tile immediately to the right). It is 3.329.
Then calculate the x value when y goes to 4 (the border to the tile immediately above). It is 5.346.
Starting at 2,3 and moving right gets to 3,3.329. Moving up gets to 5.346,4. You intersect on the right(moving 2 -> 3 on x doesn't move a tile on y). You don't intersect above until you are on tile 5 in the x.
The tile calculated in 4 becomes your new comparison (3,3). Repeat from step 2.
This process only incurs one calculation per tile moved (regardless of your precision or how big the tiles are) and is exact. Note that the values calculated can be stored and reused instead of blindly calculating both intersections over and over. In the above we know (step 4) that we don't move up a tile until x=5. So the entire path can be inferred without another calculation (2,3 -> 3,3 -> 4,3 -> 5,3 -> 5,4).
It is also possible to precalculate all the transistions instead of doing them stepwise although this would only be beneficial if you always need the entire path (you don't since you want to stop processing once you find an obstacle).
Two caveats. Be careful about signs and which way the line is going - many a bug happen by not paying close attention to negative slopes. Also, using reals you almost never will cross diagonally (two borders at once) but you should be aware of it (handle it in the code) just in case.
There is a name for this method but I can't remember it off the top of my head. I believe it might be from Game Programming Gems series but maybe someone else can provide a better reference.