recognizing rectangles, lines, etc. in 2geom, like "isrect()"???
This is sort of a follow up question to my previous one about circles. Is there in 2geom a set of methods along the lines of:
isRect(path) isTriangle(path) isLine(path)
which return true if the path has the specified geometry?
I need the first one and don't want to reinvent the wheel.
Thanks,
David Mathog mathog@...1176... Manager, Sequence Analysis Facility, Biology Division, Caltech
On 16-Dec-2013 14:45, mathog wrote:
This is sort of a follow up question to my previous one about circles. Is there in 2geom a set of methods along the lines of:
isRect(path)
Note that isRect() should be true for both
(0,0) (100,0) (100,20) (0,20)
and
(0,0) (100,0) (100,5) (100,15) (100,20) (0,20)
That is the path has the geometry specified, but it need not be have the minimum number of points.
(However if it doesn't have the minimum number of points then I am also going to need something like:
Geom::PathVector vertices = RectVertices(path); )
Thanks,
David Mathog mathog@...1176... Manager, Sequence Analysis Facility, Biology Division, Caltech
On 16-Dec-2013 14:52, mathog wrote:
On 16-Dec-2013 14:45, mathog wrote:
This is sort of a follow up question to my previous one about circles. Is there in 2geom a set of methods along the lines of:
isRect(path)
Note that isRect() should be true for both
In the patch for bug 1263242 here
https://bugs.launchpad.net/inkscape/+bug/1263242
these 3 functions were added to emf-print.cpp.
Geom::Path pathv_to_simple_polygon(Geom::PathVector const &pathv, int *vertices); Geom::Path pathv_to_rect(Geom::PathVector const &pathv, bool *is_rect, double *angle); Geom::Point get_pathrect_corner(Geom::Path pathRect, double angle, int corner);
They probably should be in src/helper/geom.cpp, but at the moment the only code that uses them is in emf-print.cpp, so there they are. (The names are maybe not exactly right for what these do.)
The first function returns a path in which any points on a polygonal path (stored in a PathVector) that are not at a vertex have been eliminated. It also eliminates one point where two fall within epsilon of each other. (Duplicate points, not sure what the technical term for them is.) If the pathvector holds more than one path or has any curves that are not linear then it returns an empty path.
The second analyzes a PathVector to see if it is a rectangle. It does this by first calling the preceding function, then checking that the path has 4 sides and that each side is 90 degrees from its two neighbors. If that is the case is_rect comes back true. The angle returned is that of the minimal rotation that will align the sides of the rectangle with the X and Y axes.
The third returns the coordinates of the Upper Left, Upper Right, Lower Right, and Lower Left corners of the rectangle, as determined by the value of "corner", given the rotation angle and path returned by the preceding function.
It would not surprise me to learn that these functions are already somewhere in Inkscape, but when I looked I could not find them.
Regards,
David Mathog mathog@...1176... Manager, Sequence Analysis Facility, Biology Division, Caltech
Hi David,
On Fri, Dec 20, 2013 at 02:55:00PM -0800, mathog wrote:
In the patch for bug 1263242 here
https://bugs.launchpad.net/inkscape/+bug/1263242
I can't work out how to get to your patch from this link.
these 3 functions were added to emf-print.cpp.
Geom::Path pathv_to_simple_polygon(Geom::PathVector const &pathv,
int *vertices); Geom::Path pathv_to_rect(Geom::PathVector const &pathv, bool *is_rect, double *angle); Geom::Point get_pathrect_corner(Geom::Path pathRect, double angle, int corner);
The first function returns a path in which any points on a polygonal path (stored in a PathVector) that are not at a vertex have been eliminated. It also eliminates one point where two fall within epsilon of each other. (Duplicate points, not sure what the technical term for them is.) If the pathvector holds more than one path or has any curves that are not linear then it returns an empty path.
This name is not quite ideal, a simple polygon is one which also has no self intersections, something you don't guarantee. Perhaps describe what it does: remove_superfluous_vertices ?
The second analyzes a PathVector to see if it is a rectangle. It does this by first calling the preceding function, then checking that the path has 4 sides and that each side is 90 degrees from its two neighbors. If that is the case is_rect comes back true. The angle returned is that of the minimal rotation that will align the sides of the rectangle with the X and Y axes.
Sounds good, definitely could go in 2geom.
The third returns the coordinates of the Upper Left, Upper Right, Lower Right, and Lower Left corners of the rectangle, as determined by the value of "corner", given the rotation angle and path returned by the preceding function.
You might construct this using the Rect::corner function combined with multiplication by a rotation.
njh
I prefer to declare variables as I use them, but I can't remember what style the code uses. Can you check please.
+ if(Geom::are_near(dot(v1,v2),1.0)){ // P1 is within a straight line
I would use cross here, which is more numerically stable in this case because it has error that is linear rather than quadratic with divergences (I think).
+ if(Geom::are_near(cross(v1,v2),0.0)){ // P1 is within a straight line
Can you fix the spacing up to match the code - you've go a somewhat arbitrary mix of no space, single space and double space around operators.
Other than that, it looks fine.
njh
On 21 Dec 2013, at 02:18, Nathan Hurst <njh@...1927...> wrote:
I prefer to declare variables as I use them, but I can't remember what style the code uses.
Yes, we define variables at the point where we need them, so we know how to initialize them meaningfully. I find it makes for hard to maintain code to define variables up front (especially without meaningful initialization).
<rant, please skip> It is 2013, and it is fine to write C99 (or newer) code. And because Inkscape and 2Geom are C++, one should use that language, i.e. not define all variables at start of scope. One thing that is easily overlooked is that "int i;" has different semantics from "Path p;". In "int i;", i is not initialized at all; in "Path p;", p _is_ initialized with the default Path constructor. This possibly confusing point is another reason not to use the pattern unnecessarily. </rant>
- Johan
Can you check please.
if(Geom::are_near(dot(v1,v2),1.0)){ // P1 is within a straight line
I would use cross here, which is more numerically stable in this case because it has error that is linear rather than quadratic with divergences (I think).
if(Geom::are_near(cross(v1,v2),0.0)){ // P1 is within a straight line
Can you fix the spacing up to match the code - you've go a somewhat arbitrary mix of no space, single space and double space around operators.
Other than that, it looks fine.
njh
Rapidly troubleshoot problems before they affect your business. Most IT organizations don't have a clear picture of how application performance affects their revenue. With AppDynamics, you get 100% visibility into your Java,.NET, & PHP application. Start your 15-day FREE TRIAL of AppDynamics Pro! http://pubads.g.doubleclick.net/gampad/clk?id=84349831&iu=/4140/ostg.clk... _______________________________________________ Inkscape-devel mailing list Inkscape-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/inkscape-devel
participants (3)
-
Johan Engelen
-
mathog
-
Nathan Hurst