Issue:
Ran into an interesting problem at work today. I am trying to build a multi path planner algorithm with some interesting rules. I wanted to get the communities thoughts on approaches while I work on whatever I try first. Hoping this is a solved problem already and I just don't know the search terms.
Rules:
There are Nr red start points, there are Nb blue start points. You must draw one path for each start point.
Each path should only intersect once for each combination, for instance path red_1 may only intersect path blue_1 at a single point.
Paths of the same color need to maintain D(istance) from each other and by extension may not intersect. Paths must be contagious to start.
Paths have width 0 < W < 1/3 D.
Paths may not exit the region of interest.
The region is an arbitrary polygon, it may be convex or concave.
Start positions should be predefined by may be placed anywhere within the area of interest or on its edges.
Goal:
Paths should cover as much of the area of interest as possible.
A first pass:
Draw red lines vertically
If red line too close to another on right, move left
If red line too close to another on left, move right
Remove one line from any pair of red lines too close
Draw blue lines horizontally
If blue line too close to another below, move up
If blue line too close to another above, move down
Remove one line from any pair of blue lines too close
Example of random starts in square region
Complete C++ code for this application at https://github.com/JamesBremner/aris2
I have added convex polygon regions of interest, here is an example for a triangular region
Related
I tried to give each rectangle a different color but unfortunately it did not work
I want the horizontal distance between those two rectangles to be zero
Here is what I want:
And here is the code and result: http://www.plantuml.com/plantuml/uml/rP9FIyD04CNl-ocMUXEAIMn198PYeE1PZu9iacawT3CRPgSjMlpkhfiISoXuyEISNjuly-V1hhmObdrdbTyXzOPDfviUzI999exVciOTaLgzCTR3X5IcthNizjJKpZhMmePyG42YrEG_XbeCjHRqIUbGiQLqJC0wNKRhMO31oNiFQqTInd5NbGqB8hveFexhpsWTQs2E6-2pdoJBzAvKwZDSzNFBBFVu0VTPLhoWXEyql_asYbSQG5hacx1MnsmFnoqA54W7z5XPc1-01MjZvo5mZTIEpM-X_ZZYMZy9T3eTLJQgszdfjnpPlyWngiK5jHnIhe2Qy3g_0000
but the most important thing to set the horizontal distance between these two rectangle to zero
It's not possible to do a 0 horizontal distance between two rectangles in PlantUML. You could do a table in Creole, but it won't look like your example, since the lines (rows) would be aligned in a table.
When I see your usage, I think you'd be better off using DOT (GraphViz). You can wrap DOT code in #startdot/#enddot in a PlantUML engine and it will draw the diagram. For example:
https://www.plantuml.com/plantuml/uml/TP1HIyCm58NVyol2_GDJvfj9MDkK8PIbn88FOm_PShN5q9OqeY3-TvDfApBMXzwSd2_dmDrCmVXWXq1iz-BDsD8f-BTJcEWdeV7h1ujqFxLcH3uwq_K1Fy8XMR_WckwTEQBZZB0cowkIvahBKdEu0LgKLJNBsn_vM6V5mswxs7KcvLdV0SstXQfKP7KfGSGIrkWqqa5IhPxYuns7DOWMdHjOhbVYVV3EibKZ_y0Oie37sOfJNqGkXMFNlu8udU5ar4et75hq2CBEjmAlX5tMFlydup-jHeZ3FVaY6-njtFWt
But, since you're writing lower-level DOT, you need to use that syntax to lay everything out. There is much more control, but it's no longer PlantUML.
Given a number of points on a 2d surface and radiuses for these points I can easily paint circles for them. What I need is an algorithm that only paints the envelope (right word for what I am looking for?) or outer bound of these combined circles. Additionally a second set of circles can 'encroach' on these circles, resulting in a kind of 'border'.
Image of what I am looking for
A quick way to draw the outline of the union of the disks is to
fill all disks in yellow, then
fill all disks in white with a smaller radius.
This can be adapted to the "encroached" circles, provided you only fill the remaining portions of the disks. Unfortunately, in a general setting finding the remaining portions can be an uneasy geometric problem.
There is an alternative approach which can work in all cases:
fill an image with zeroes, then for all disks fill every pixel with the value of the distance to the circumference (maximum at the center), but only keep the highest value so far.
while you do this, fill a second image with the color of the disk that achieved that highest value. (Initialize the image with the background color.)
At the end of this process, the first image will represent a "terrain" made of intersecting cones; and for every point of the terrain, you will know the color.
finally, color the pixels that have a height smaller than the desired stroke width, using the color map.
You can do the drawing in two steps.
1) Draw the outline using the following method: For each point, draw a circle using your favorite circle-drawing method, but before drawing a pixel, ensure that it is not contained inside any other circle. Do this for every point and you will get your outline.
2) Draw the borders between different sets using the following method: For each pair of points from different sets, calculate the two intersection points of the circles. If there is an intersection, the border can be drawn as a segment joining these two points. However, you have to make two lines, one for circle A, and another for circle B. To draw the line for circle A, slightly offset the segment towards point A. Then, use your favorite line-drawing method, but before drawing a pixel, ensure that it is closer to point A that any other point of the opposite set. After drawing the line, repeat the process for circle B. Note that both segment are not guaranteed to be the same length since the asymmetry of the points of the different sets. It will, however, always form a closed shape when all outlines and borders are drawn.
Concerning tree searching algorithms, particularly quad-tree and r-tree, how do they account for edge errors when finding nearest neighbors. I'm not good at explaining this with words so I made some pictures.
For the picture the input coordinate to find the nearest neighbor is green, what I would assume end up being the "found" nearest neighbor is red. The actual nearest neighbor is blue.
In this quad-tree, the blue lower-right quadrant would be searched in with only that one red point while in actuality, the input coordinate (green) is so close to the edge it's actually closer to the blue point.
Similar with an R-tree if the coordinate is within one rectangle but so close to the edge it's closer to a point in another rectangle like below, where white dot is given coordinate:
It's wholly within the red box but closer to a point in the magenta box.
In both cases it is necessary to do a fine-grain distance check between elements - the boxes or divisions just help find candidates for the real distance check.
A way to look at it is, use the boxes to tell you what NOT to check. If an entire box is farther away than something you already know, you don't need to check anything in that box. If some of the box is close, better check the elements in it.
If you would bother to read the R-tree publication...
It uses a minimum distance, of the query point to a neighboring page.
If mindist(query, rectangle) <= dist(query, known neighbor) then the search needs to continue in the other rectangle, because there could be a better neighbor there.
It's actually quite straightforward, and should be explained in any book on R-trees and similar indexes.
I have xy grid, where points have whole-numbered, positive coordinates. These points are "neighbours" if both their x and y coordinates differ by less than 2 - they are simply next to each other.
In this grid, I have found path that encloses some area. Every point in the path is neighbour to the previous point and the next point, so it is sorted like you walked around the enclosed area. It is also shortest path around that enclosed area, so there are no steps back and forth. The enclosed area does not need to be convex, so when you connect two random points on the path with one line, that line can lie completely out of that area.
The problem is, I need to find at least one point in enclosed area, that is neighbour to any point in enclosing path.
It might sound easy, but I have not found solid algorithm to determine it.
* I'm sorry, I did not explain that well enough. There are no "empty parts" in enclosed area. If there are three points in enclosed area, the path around is the smallest path that captures those three points. In this picture, red path is shortest, black is too long and I never need to detect those.
Observations to check that I understand the question:
It's possible that there are no such interior points.
Given that consecutive path point are neighbors, the connection
angles will be at multiples of 45°.
The basic idea is to walk the path and keep track of interior and exterior neighbors.
To determine which side is the interior, walk the path and keep track of the cumulative turn angle. The final amount will be 360° or -360° which will indicate the interior is on the left or the right, depending on which way you defined positive and negative angles.
During that first pass, also collect a hash set of the points on the path, onPathPoints.
Initialize two other hash sets to empty: exteriorPoints and possibleInteriorPoints.
Walk the path and for each point:
a. categorize the 8 neighbors as on-path, interior-side or exterior-side based on the relative positions of the previous and next points on the path.
b. for each point in onPathPoints, ignore it.
c. for any point on the interior side and distance 1 away, return that point as the result.
d. for each points on the interior side with distance > 1 (diagonal neighbor), add it to possibleInteriorPoints.
e. for each point on the exterior side and distance 1 away, add it to exteriorPoints.
At the end of the walk, remove from possibleInteriorPoints any point in exteriorPoints (set subtraction). Return any point remaining in possibleInteriorPoints as an interior point.
Otherwise, there are no interior points.
The possibleInteriorPoints represent diagonally neighboring points that are in the interior unless the path loops back between the original point and it (in which case it will be an exterior point to the new path part.
For example in the image below, when visiting (2,2) and going toward (3,3) the interior is on the right. (3,1) is a possible interior point, but later in the walk while visiting (4,1), (3,1) is noted to be an exterior point and so would get removed from possibleInteriorPoints.
Technically, in this example the algorithm would have stopped when visiting (4,3) and noting (4,2) as an interior point at distance 1.
How i can add a multi-line text with itext on diagonal. meaning that if the text is to large for the first diagonal(the largest diagonal) it should move on the next or above diagonal and so one, to see all the text.
I already calculated the text angle for the diagonal and uses pdfcontentbyte to stamp but if my text is longer than the diagonal the rest of the words that don't fit on the diagonal it is not showed. I think i have to make something mathematical or i saw something with setsimplecolumn and chunks but this will show my text aligned horizontal.
If anyone has some ideas? Thanks, and of course need some code examples.
Don't shoot me if I'm wrong, but based on your description I think you're talking about 'irregular columns'. See http://itextpdf.com/examples/iia.php?id=67
This type of column isn't a rectangle. Basically, you define coordinates for the left border (can be a diagonal line) and coordinates for the right border. Then you pour text between these two lines.
If that's not what you meant, maybe you want to write text diagonally. In that case, you can still use ColumnText, but you need to change the coordinate system, so that the text isn't written in horizontal lines from left to right, but in diagonal lines from top to bottom (or bottom to top). Changing the coordinate system is done with the concatCTM method.