Tuesday, August 22, 2017
Aesthetics are the most important thing about a computer language. Lazy or eager, imperative or declarative, object or aspect, template or macro, strong or weak, none matter as much as pleasant to the eye and mind. Assembly had equilength lines. Lisp was conceptually simple, but impossible to look at. C had logical sounding key words, like if, for, goto. C++ had good salesmanship. Haskell has significant indentation. But to properly take advantage of this most crucial feature of Haskell, one must use single space indentation, and only when absolutely necessary. Also, keep lines and identifiers short. Except after >>=, use one character identifiers near the end of the alphabet for lambda arguments, and except for clarity, use one character identifiers near the start of the alphabet for named function arguments. Name lemma functions the same as the main function, except with a single capital letter suffix. Use let instead of where, unless the variable is used in guards or multiple branches. Except to break a rule, never use do notation. Freely pass IO arguments to functions other than >>= and >>. Use <$> and <*> sparingly. Get to the let as soon as possible in IO functions.
Friday, April 7, 2017
Sculpt displays a polytope, and in interactive mode, the left mouse button (de)selects pierce point(s), changing mode deselects pierce point(s), and the right mouse button switches modes with a menu. Mouse modes are rotation about the pierce point, translation of the pierce point, and rotating about the focal point. Roller button modes are rotation about the pierce point line of sight, scaling from the pierce point, driving forward to and back from the pierce point. Moving the operating system window also translates, so the model appears fixed behind the screen. Mouse and roller button modes are a matrix of submodes of transform mode. Nontransform modes are random refinement through the pierce point with roller button controlled cursor warp, additive sculpting above the pierce point, subtractive sculpting under the pierce point, and pinning two pierce points and moving a third pierce point by mouse and roller button.
Directory .script, or the -d directory, has numeric, space, embedding, and polytope representations saved, timestamped, classified by backlink automatically, and named manually. And .script, or the -d directory, has configurations such as light color and direction, picture plane position and directions, focal length, window position and size, and refine warp.
Option -i starts interactive mode, -e "script" loads a metric expression to periodically display heuristic animation, -d "dir" changes directory, -n "dir" initializes new directory with current state, -r randomizes the lighting -o "file" saves format by extension, -f "file" loads format by extension, -l "shape" replaces current by builtin shape, -t "ident" changes current by timestamp or name. Options are processed in order, so interactive sessions, animations, directory changes, initializations, loads, and saves can occur in any order. If .script or -d directory does not exist or is empty, it is created with regular tetrahedron, random lighting, and window centered on screen. It is an error for -n directory to exist, for -f file to not exist, or for -o file to exist. Errors are recoverable because directories contain history, and error messages contain instructions on how to recover.
The look and feel of sculpt is turn based. Even metric driven animation only updates the displayed vertices periodically. The rotations and such occur continuously through matrix multiplication, but the model remains rigid. Pin and move of plane is represented by wire frame, updating vertices and possibly faces only after action completion.
Supplemental features to sculpt include graffiti on faces, windows to other polytopes on faces, system calls and icons on faces, sockets to read-only polytopes on faces, jumping through faces to other polytopes, user authentication and kudos for various modifications to polytopes from requests through socket
Wednesday, April 5, 2017
The properties of polytopes that I chose to keep invariant are discontinuities, flatness, colinearity, and convexity. To indicate that two points on a polytope are colinear, or cohyperplanar, I collect the points into boundaries and intersections between boundaries, such that two points are coplanar iff they are in the same boundary. The discontinuities in a polytope occur only where boundaries intersect. To understand convexity, note that intersections between halfspaces are convex. Thus, if a discontinuity is concave, it consists of more than one halfspace intersection of the same intersecting boundaries. I call the halfspace intersections polyants, and specify them as maps from boundary to side. Thus, in an n dimensional space, a vertex has 2^n polyants, and an edge has 2^(n-1) polyants. If more than one polyant of a vertex has points near the vertex in the polytope, then the vertex is not convex, and similarly for edges, and so on. Note that the polytope has only the empty polyant, and the single boundaries each have two polyants. Wrt a boundary in its domain, a polyant is significant iff points in the polyant near the boundary are near points both in and not in the polytope. In fact, a two boundary polyant is significant iff one of the boundaries is significant in the section of the polytope by the other boundary. Thus, a polytope is a graph of polyants. Since a polyant is specified by boundaries and sides, and a graph is a map from polyant to set of polyant, equivalent polytopes are found by permuting the boundaries and mirroring sides across boundaries.
Friday, March 31, 2017
I know nothing about representation theory, but in this context, a representation is a set of tuples. A relation is a set of two element tuples, and a function is a relation in which the first element of each tuple occurs in no other tuple. You can think of a relation as a function with range elements that are sets. Thus, the result of the function is the set of second tuple elements of tuples that have the function input in the first element. You can think of multivariable functions as sets of tuples with more than two elements. In prior posts, I represented space as a matrix of sides, where row(column) indicated boundary, and column(row) indicated region. In my Haskell code, the first representation I chose was a list of lists of region sets. The position in the outer list indicated boundary, and the position in the inner list indicated side. In subsequent representations, I indicated the boundary explicitly, instead of implicitly by list position. I also used representations where the innermost sets are sets of boundaries instead of regions. Whenever I came up with a new representation, I worried whether I could convert between one and another. Now that I understand representations are just sets of tuples, I no longer worry about converting; converting is as simple as changing the order of the elements in the tuples. In future computer architectures, I predict the preferred representation will be sets of tuples. In a computer, a set of tuples could be implemented as a CAM, a content addressable memory. The challenge would be to make the CAMs in the computer completely configurable. Right now, we are limited to RAMs, random access memories, because they are relatively easy to implement. Note that even RAMs are not completely configurable, some sequences of access are more efficient than others, depending on the particular implementation.
Wednesday, March 29, 2017
In my Haskell code, I chose to represent sets as lists. In practice, this means I have to prevent duplicates in the lists that represent sets. Just to be difficult, I also use lists for ordered pairs of same type things, or maps from index to things. If the things are of different type, then ensuring there are not duplicates is a no-brainer and they might as well be ordered, so I use tuples. This is all very mathematical, and functions resemble constructive proofs. Where computational functions differ from proofs is in which shortcuts are taken. Proofs don't care how long they take to execute. Computer functions are expected to complete in a reasonable time. I use a function called choose to document when I am deviating from the mathematical ideal to make a function more computational. Choose is defined as head; it returns the first element of the list. Choose is intended for use only on lists representing sets, but that is not the only intended restriction on its use. Choose is intended for use when any element of the set would be correct, and the choice of element changes the result of a function it is directly or indirectly used in. Where the choice would not affect the result, I use head. The reason this makes the functions using choice less mathematical and more computational is that the alternative is to return all valid results, not just one valid result. For example, my superSpace function uses choose often to simplify the computational problem, even though the simplest solution to the mathematical problem is that there are multiple solutions.
Friday, March 24, 2017
Till now, I have focussed on irregular spaces and polytopes without coincidental boundaries, but spaces with missing regions have been a nagging possibility. For example, if a space is caught in the process of migrating, then the migration itself is like a sidedness space with a missing region, or an affine space with more than the dimension's worth of boundaries through a point. Parallelism is also a a form of degenerate space. Imagine a migration of a round space, where the migrating region is an outside region in a flat rotation space of the round space. Now consider embeddings of polytopes into spaces. Since an embedding is a subset of the regions in the space, one can specify the embedding as the degenerate space consisting of just the embedded regions. Restoring the degenerate space to a linear space is one to many, but each restoration is a valid embedding of the same polytope. Now note that regular polytopes contain parallel sides. Irregular and regular polytopes are both degenerate spaces; the only distinction is whether there is a partial restoration to a space missing outside regions.
Thursday, March 23, 2017
To find equivalence classes of spaces, and of polytopes, it is impractical to try all permutations of a representation to find if it makes one equal to another. Assuming permutations of representations are comparable as greater or lesser, an approach would be to find the permutation that minimizes a representation the most. Then all equivalent representations would minimize to the same member of the equivalence class. To find the minimizing permutation, choose transpositions such that the first transposition chooses which identifier will be the smallest. Of course, multiple transpositions could cause the smallest identifier to be first in the representation. Some transposition sequences would get weeded out only after subsequent transpositions failed to compete with their peers. Weeding out transposition sequence prefixes as unable to recover potential after failing to put the smallest identifiers first in the representation is justified because no subsequent transposition affects the position of lesser identifiers. This algorithm is not O(n), but it is potentially, and I suspect in practice, much better than the O(n!) of the naive approach of trying every permutation. Since I needed to use the same algorithm for both spaces and polytopes, I created a Haskell class of permutation types. Each permutation type must implement refine and compare functions. A refine function returns a list of permutations, each with one more transposition than the given permutation. A compare function takes two partial permutations and compares their application to a representation. To accomplish the compare function, each type in the class is actually a wrapper around an original representation and a partial permutation of that representation.