ClipperLib documentation about offset operation says among preconditions:
The orientations of closed paths must be consistent such that outer polygons share the same orientation, and any holes have the opposite orientation (ie non-zero filling). Open paths must be oriented with closed outer polygons.
(emphasis mine)
What is the definition of orientation for an open path?
The definition of orientation makes sense only for closed paths, that is a typo in the documentation.
Also if the input is not sorted and oriented (i.e. the area you want to offset is defined as a collection of closed loops assuming even-odd filling rule and it's unknown what loops are holes and what are boundaries) a solution is to perform the operation in two steps
Compute the x-or of all the loops as a boolean operation
Compute the offset of the result
This is possible because results from clipperlib operations are always sorted and oriented.
Related
I have a floor-plan drawing with several rooms defined by enclosed polylines. There are several text annotations inside each polyline (room-number, room-name, etc).
How can i make a routine thats scans the drawing, builds a selection-set that finds each polyline (resides on a specific layer) and inserts a block (room_stamp) with attributes corresponding to those annotations.
So for example, for every room it would insert the block "room_stamp" inside the polyline, grab the text inside the polyline which belongs to the layer "room_name" and change the attribute "room_name" inside the block to match it.
Any help would be much apreciatted as I am just starting with LIPS routines
The first step would be to obtain a selection set of all closed polylines residing on the target layer - for this you would use the ssget function with the X mode string argument (to scan the entire drawing database with no user input), and a filter list argument filter on entity type (DXF group 0), and layer (DXF group 8), and optionally on the bit-coded DXF group 70 to restrict the selection to closed polylines only - you may wish to refer to my ssget Function Reference to assist with the construction of this expression.
On obtaining a selection set of polylines on the target layer, you would then iterate over this set (there are many methods to do this), and for each polyline you have one of two options:
Obtain a window polygon/crossing polygon selection set of all text (perhaps restricted to a target layer) by supplying the ssget function with the WP or CP mode string, the set of polyline vertex coordinates, and an appropriate filter list.
Obtain a selection set of all candidate text objects within the active layout/viewport and use a ray-casting algorithm or similar to test whether the insertion point of each text object resides within the boundary of the polyline.
Method (1) is the easiest, but could also be the least reliable, as the graphical selection methods of the ssget function will only consider objects visible within the drawing area at the time of function evaluation - hence, for greater accuracy, you would first need to zoom to each polyline before acquiring the selection of the objects it encloses, and then restoring the previous view.
Method (2) is more reliable in that it is independent of the state of the graphical display in AutoCAD, but will be slower as it requires more calculation and iteration over the entire set of candidate text objects (unless you implement a divide & conquer technique through clever use of pre-sorting the set).
Upon acquiring the set of text objects residing within the polyline, you'll need some way to differentiate each text object in the set, so that you populate each attribute with the appropriate value. This will be completely dependent on your data - e.g. whether each item of data resides on its own layer (for example, do all of the room numbers reside on their own layer, and all room names on another?), or can you use pattern matching on the text content to identify a room number from a room name and other information?
With the appropriate values determined, it is relatively straightforward to insert a new attributed block reference (perhaps at the centroid of the polyline, or at the insertion point of one of the existing text objects) and populate the block attributes with the values acquired from the text - there are many existing examples of this.
This is a follow-up to a suggestion by #DCTLib in the post below.
Cudd_PrintMinterm, accessing the individual minterms in the sum of products
I've been pursuing part (b) of the suggestion and will share some pseudo-code in a separate post.
Meanwhile, in his part (b) suggestion, #DCTLib posted a link to https://github.com/VerifiableRobotics/slugs/blob/master/src/BFAbstractionLibrary/BFCudd.cpp. I've been trying to read this program. There is a recursive function in the classic Somenzi paper, Binary Decision Diagrams, which describes an algo to compute the number of satisfying assignments (below, Fig. 7). I've been trying to compare the two, slugs and Fig. 7. But having a hard time seeing any similarities. But then C is mostly inscrutable to me. Do you know if slugs BFCudd is based on Somenze fig 7, #DCTLib?
Thanks,
Gui
It's not exactly the same algorithm.
There are two main differences:
First, the "SatHowMany" function does not take a cube of variables to consider for counting. Rather, that function considers all variables. The fact that "recurse_getNofSatisfyingAssignments" supports cubes manifest in the function potentially returning NaN (not a number) if a variable is found in the BDD that does not appear in the cube. The rest of the differences seem to stem from this support.
Second, SatHowMany returns the number of satisfying assignments to all n variables for a node. This leads, for instance, to the division by 2 in line -4. "recurse_getNofSatisfyingAssignments" only returns the number of assignments for the remaining variables to be considered.
Both algorithms cache information - in "SatHowMany", it's called a table, in "recurse_getNofSatisfyingAssignments" it's called a buffer. Note that in line 24 of "recurse_getNofSatisfyingAssignments", there is a constant string thrown. This means that either the function does not work, or the code is never reached. Most likely it's the latter.
Function "SatHowMany" seems to assume that it gets a BDD node - it cannot be a pointer to a complemented BDD node. Function "recurse_getNofSatisfyingAssignments" works correctly with complemented nodes, as a DdNode* may store a pointer to a complemented node.
Due to the support for cubes, "recurse_getNofSatisfyingAssignments" supports flexible variable ordering (hence the lookup of "cuddI" which denotes for a variable where it is in the current BDD variable ordering). For function SatHowMany, the variable ordering does not make a difference.
In Postgis there are two very similar functions. One is st_isValid, the other one is st_isSimple. I'd like to understand the difference between both for Polygons. For the st_isValid we have:
Some of the rules of polygon validity feel obvious, and others feel arbitrary (and in fact, are arbitrary).
Polygon rings must close.
Rings that define holes should be inside rings that define exterior boundaries.
Rings may not self-intersect (they may neither touch nor cross one another).
Rings may not touch other rings, except at a point.
For the st_isSimple we've got:
Returns true if this Geometry has no anomalous geometric points, such as self intersection or self tangency. For more information on the OGC's definition of geometry simplicity and validity, refer to "Ensuring OpenGIS compliancy of geometries"
Does it mean that any valid polygon is automatically simple?
Both functions check for similar OGC definition compliancy of geometries, but are defined for different geometries (by dimension);
By OGC definition
a [Multi]LineString can (should) be simple
a [Multi]Polygon can (should) be valid
This implies that
a simple [Multi]LineString is always considered valid
a valid [Multi]Polygon is always considered simple (as in, it must have at least one simple closed LineString ring)
thus the answer is yes.
Strictly speaking, using the inherent checks of the OGC defined functionality on the 'wrong' geometry type is useless.
PostGIS, however, liberally extends the functionality of ST_IsValid to use the correct checks for all geometry types.
In Haskell or some other functional programming language, how would you implement a heuristic search?
Take as an example search space, the nine-puzzle, that is a 3x3 grid with 8 tiles and 1 hole, and you move tiles into the hole until you have correctly assembled a picture. The heuristic is the "Manhattan heuristic", which evaluates a board position adding up the distance each tile is from its target position, taking as the distance the number of squares horizontally plus the number of squares vertically each tile needs to be moved to get to the correct location.
I have been reading John Hughes paper on pretty printing as I know that pretty printer back-tracks to find better solutions. I am trying to understand how to generalise a heuristic search along these lines.
===
Note that my ultimate aim here is not to write a solver for the 9-puzzle, but to learn some general techniques for writing efficient heuristic searches in FP languages. I am also interested to learn if there is code that can be generalised and re-used across a wider class of such problems, rather than solving any specific problem.
For example, a search space can be characterised by a function that maps a State to a List of States together with some 'operation' that describes how one state is transitioned into another. There could also be a goal function, mapping a State to Bool, indicating when a goal State has been reached. And of course, the heuristic function mapping a State to a Number reflecting how well it is estimated to score. Other descriptions of the search are possible.
I don't think it's necessarily very specific to FP or Haskell (unless you utilize lists as "multiple possibility" monads, as in Learn You A Haskell For Great Good).
One way to do it would be by writing a recursive function taking the following:
the current state (that is the board configuration)
possibly some path metadata, e.g., the number of steps from the initial configuration (which is just the recursion depth), or a memoization-map of all the states already considered
possibly some decision, metadata, e.g., a pesudo-random number generator
Within each recursive call, the function would take the state, and check if it is the required result. If not it would
if it uses a memoization map, check if a choice was already considered
If it uses a recursive-step count, check whether to pursue the choices further
If it decides to recursively call itself on the possible choices emanating from this state (e.g., if there are different tiles which can be pushed into the hole), it could do so in the order based on the heuristic (or possibly pseudo-randomly based on the order based on the heuristic)
The function would return whether it succeeded, and, if they are used, updated versions of the memoization map and/or pseudo-random number generator.
I've been building a parser for STEP-formatted data (specifically the ISO 10303-21 standard), but I've run into a roadblock revolving around a single character - '$'.
A quick Google search reveals that in STEP, this character denotes an 'unset' value, I interpreted this as an uninitialized value, however I don't know exactly what I should do with it.
For example, take the following definitions:
#111=AXIS2_PLACEMENT_3D('Circle Axis2P3D',#109,#110,$) ;
#109=CARTESIAN_POINT('Axis2P3D Location',(104.14,0.,0.)) ;
#110=DIRECTION('Axis2P3D Direction',(1.,-0.,0.)) ;
To me I cannot see how this would even work, as the reference direction is uninitialized, and therefore an x-axis cannot be derived, meaning that anything using this Axis2Placement would also have undefined data.
Normally when I reach this point, I would just define some sort of default data for the given data-type (Vertices (0,0,0), Directions(1,0,0), etc.), however this doesn't seem to work, because there's the chance that my default direction would cause conflicts with the supplied data.
I have Googled what to do in this scenario, only to come up with nothing.
I also have a PDF for a very similar STEP format (ISO-10303-42), but it too doesn't mention any sort of default data, or provide any more insight in to how this works.
So, to explicitly state my question: what do I do with uninitialized data in STEP (ISO 10303-21) data?
You need to be able to represent 'unset' as a distinct value. It doesn't mean the same thing as an uninitialized value or a default value. For example you might represent AXIS2_PLACEMENT_3D as an object with data members that are pointers to point to CARTESIAN_POINT and DIRECTION, and the $ means that that pointer will be null in your representation.
Dealing with null values will depend on the context. It may be some kind of error if the data is really necessary. Or it may be that the data isn't necessary, such as if you don't need the axis to be oriented, and a point and direction are sufficient to represent the data.
In this case: #111 is local coordinate system with following 4 attributes:
character name;
pointer to origin (#109);
pointer to axis (#110);
pointer to second axis (reference direction).
If #111 is a coordinate system of circle (I guess it with 'name' value), axis is normal of circle plane, while reference direction points to start of circle (position of zero t parameter of circle). Since a circle is closed curve, you can locate this zero t position in arbitrary place, it has no influence on circle geometric shape, reference direction in this case is not mandatory, and is omitted. And it is your choice how you handle this situation.
When $ sign is used , the value is not required. Specifically, if there are a series of optional values and you want to specify a value for, let's say, 3rd optional argument and you don't want to specify values for the 1st and 2nd optional arguments, you can use $ sign for those two.
Take a look here for a better description.