/RefereceFinder

ReferenceFinder For origami

Primary LanguageC++

/*

ReferenceFinder - a program for finding efficient folding sequences for locating reference 
points and lines in a unit square.

Version 3.1

Copyright ©1999-2003 by Robert J. Lang. All rights reserved.

RIGHTS OF USAGE

You may distribute the compiled executable freely so long as you do not charge for it.

You may compile the code and modifications thereof for your own personal use. 
You may not redistribute this code or modifications thereof.

The software and code are supplied as-is, with no warranties of fitness for any given purpose.

ACKNOWLEDGEMENTS AND THANKS

Thanks to the following contributors:
Carlos A. Furuti -- Linux compatibility/porting and expression parser/evaluator
Robert Allan Schwartz -- Windows compatibility/porting

WHAT IT DOES

ReferenceFinder is a program that constructs folding sequences for reference points in
a square. When you run it, ReferenceFinder first builds a database of marks (points) and 
lines that have short folding sequences. This takes 30 to 90 seconds. You then select 
whether the reference you are seeking will be a point (enter 1) or a line (enter 2).

If a point, you will be prompted for its x and y coordinates, which should be between
0 and 1.

If a line, you will be prompted for the x and y coordinates of any two points on the
line. They should be distinct, obviously.

You can enter coordinates either as their decimal values (e.g., 0.4142), or as a mathematical
expression (e.g., sqrt(2)-1, or even d-1). Expressions may contain any of the operators +, -, 
*, /, ^, (), sqrt, sin, cos, tan, deg2rad and constants e/pi/phi/Phi; d is an abbreviation 
for sqrt(2), which shows up a lot in origami crease patterns. Trigonometric functions use 
radians, deg2rad converts degrees to radians.

Once you have entered the point or line, ReferenceFinder will print out verbal instructions
for 5 folding sequences that give close approximations of the the point or line you entered.
For 97% of points, the approximated point will be within 0.005 of the target point. (The other
3% are still pretty close.) Lines are similarly close to their targets.

In addition to the verbal instructions, ReferenceFinder writes a file, "ReferenceFinder_xxx.ps"
(where xxx is a number), which contains PostScript code for the folding diagrams. You can use 
GhostScript or Adobe Acrobat Distiller to convert the file to a viewable format. The numbering
restarts each time you run ReferenceFinder; if you want to keep the diagrams, move them to a
different directory or rename the file(s).

HOW IT DOES IT

There are 7 possible ways of defining a fold in terms of alignments between points
and lines (known as the "Huzita-Hatori Axioms"). ReferenceFinder starts with an unmarked
square and recursively constructs all distinct lines (and points, which are defined as
intersections between pairs of lines) that use no more than 6 sequential HHA operations.
Along the way, ReferenceFinder filters the list to weed out duplicates and folds that are 
difficult to make precisely in practice.

When you enter a point or line, ReferenceFinder searches through this list and picks out the 
points or lines closest to the one you entered.

FOR MAC, WINDOWS, LINUX, AND/OR NON_PROGRAMMERS

The distribution contains a folder, /executables/, that contains executables for Mac, 
Windows, and Linux.
/mac/ReferenceFinder 3.1 -- runs on Mac OS 9 and X. 
/mac/ReferenceFinder 3.1 Classic -- runs on OS 8.
/win/ReferenceFinder 3.1 -- runs on Windows 98 and XP (I'm not sure about others; try it.)
/linux/ReferenceFinder -- runs on Linux on i586.

FOR OTHER PLATFORMS AND/OR PROGRAMMERS

ReferenceFinder is ANSI C++ code that should compile for any compiler/platform
that supports the C++ standard library. For ease of portability, ReferenceFinder is a
text-based program that uses the standard console, cin and cout, for user interaction. 
However, it has a fairly clean API that supports integration with a GUI and/or a 
variety of imaging models for the diagrams, if anyone were so inclined to write one.

The source code consists of:
lexer.h -- header for the lexical analyzer
lexer.cpp -- implementation of the lexical analyzer
parser.h -- header for the expression evaluator
parser.cpp -- implementation of the expression evaluator
ReferenceFinder.h -- header for reference point/line construction and searches
ReferenceFinder.cpp -- implementation for reference point/line construction and searches
ReferenceFinder_console.cpp -- a console-based main program.

(Linux/Unix specific)
makefile.unx -- compatible with most versions of "make"

(Mac specific)
carb.r -- resource file needed for Carbon compliance on Mac
ReferenceFinder_mac.mcp -- CodeWarrior 8 project file with targets for Mac and Win32

For other compilers and/or platforms, ReferenceFinder 3 should compile with minimal modification 
for any compiler that supports the C++ standard (including templates). Email me if you find 
bugs or incompatibilities. 

ReferenceFinder uses a lot of memory during initialization. You should allocate 60 MB of RAM
to the program.

PROGRAM NOTES AND HISTORY

Version 3.1b1

-- Added more information to verbal output and PostScript diagrams, including the target
	point and coordinates of each solution point.
-- Added number to ReferenceFinder_xxx.ps so you can find multiple points within a single
	session without having to rename the file after every search.

Version 3.0, released 2003-06-12.

-- Minor cleanups to README.txt.

Version 3.0b8

-- From Carlos: in order to avoid portability problems, all-new lexer.cpp/h fully replace 
        expr.l/lex.yy.c/y.tab.h. Patched parser.cpp and parser.h now fully C++ citizens; 
	no more global vars or yacc types. 
	ReferenceFinder.cpp suffered minor changes:
	- several switch cases left unhandled, now marked explicitly
	- added a void* parameter to the progress callback. It can be useful at a GUI 
	  if no global vars are available to give context. Incidentally it's not needed in my
	  particular wxW GUI.
	ReferenceFinder_console.cpp: typing  <Enter> is accepted as zero, except at the
          0/1/2 prompt
	Makefile.unx had a little polish.
	parser.cpp/expr.l: RJL's fixes for compiling in CodeWarrior (interim from b7) no
	  more necessary with new lexer.
	ReferenceFinder.cpp - in lines 4567 and 4537, "%Page" should be "%%Page" - it's all my fault

Version 3.0b7

-- New and improved parser from Carlos!
	Files changed:
	- makefile.unx (creates executable in executables/linux)
	- expr.y, y.tab.c (deleted)
	- expr.l/lex.yy.c
	- ReferenceFinder_console.cpp
	- y.tab.h
	- parser.cpp, parser.h (new)
	
-- RJL has made further small changes to parser.cpp and lex.yy.c to make CodeWarrior happy.

-- Added PS comments and pagination comments to PSFileDgmr since Ghostview is not as forgiving
	as Acrobat Distiller.

Version 3.0b6

-- Reorganized distribution folders and files. Made makefiles specific to win and lin.

-- Renamed "ReferenceFinder_main.cpp" to "ReferenceFinder_console.cpp".

-- Fixed a bug in arrow generation in Axiom 1 in which arrows didn't connect mating points.

-- Fixed a bug in Axiom 7 whereby an illegal alignment (pt-to-line where pt is already on the line)
	was getting through. This slightly reduces the total number of marks and lines.
	
-- Added multipass drawing to diagrams so that (among other things) hilited lines are always on top
	of non-hilited lines and labels are always on top of everything else.

-- Fixed a bug in diagram generation that improperly hilited some refs within diagrams.

-- Added the RefBase::IsDerived() method, which was necessary to fix the diagram generation bug, but
	is also generally useful.
	
-- Added RefBase::ClarifyVerbalAmbiguities() to turn on/off additional coordinate information in
	verbal instructions that resolves ambiguities when there are multiple solutions for a given 
	alignment.
	
-- Added RefBase::SetAxiomsInVerbalDirections() to turn on/off the axiom numbers in the verbal
	directions.
	
-- Added RefBase::GetLabel(), which returns the single-character label for a mark or line (or a
	null character for original refs).

-- Minor typedef cleanup involving rank_t and index_t (typedef'd as short to minimize object size).

Version 3.0b5

-- Replaced find() and map<>.operator[] with map<>.count() and map<>.insert() for a slight speedup.

-- Moved RefLine_L2L up in priority above RefLine_P2P, since the former are what people usually 
	think of doing when folding a square in half.
	
-- Removed pragmas for portability

-- Fixed a bug in BuildDiagrams that arose if you passed a RefMark_Original or RefLine_Original.

Version 3.0b4

-- Added a new class, RefDgmr, and two examples (ConsoleTextDgmr and PSFileDgmr) for generating
	diagrams. RefDgmr provides an API for any GUI that wants to show diagrams. The old text-
	based output routines have now been rolled into ConsoleTextDgmr. The new class PSFileDgmr
	generates a Postscript file that provides folding diagrams for the most-recently-sought 
	mark or line. PSFileDgmr also provides a template for how other descendants of RefDgmr 
	might be written to implement other imaging models (e.g., OpenGLDgmr, QuartzDgmr,
	TclDgmr...).

-- Added two routines designed specifically for diagrams:
	RefBase::DrawDiagram(RefDgmr&, DgmInfo), which draws the image of a diagram using the 
	imaging model specified by the RefDgmr;
	RefBase::PutDiagramCaption(ostream&, DgmInfo), which puts the caption for a particular 
	diagram	to a stream (similar to how PutHowtoSequence puts the entire verbal description 
	to a stream).
	
-- Numerous small changes to permissions, function names, and ownership of static member variables
	for reasons of compatiblity with the new RefDgmr class (and its descendants) and general
	cleanliness of code.
	
-- Removed the sayWhat global in favor of a compiler switch, NO_CONSOLE, which, if #defined,
	suppresses all output calls to the console in compilation.

Version 3.0b3

-- Carlos updated the expression evaluator to accept leading decimal points (e.g., ".2"), 
	which it didn't used to do.

-- Moved all of the global settings (e.g., minAspectRatio, maxRank, etc.) into the new object
	ReferenceFinder. Also global search routines are now part of the object. Projects that embed
	don't have to declare anything extern, then can just #include ReferenceFinder.h.

-- Adjusted some public/protected/private permissions for RefBase methods.

-- MakeAllMarksAndLines() can now be called repeatedly if you decide to change some of the global
	settings.

Version 3.0b2 (5-12-03)

-- Added expression evaluator by Carlos Furuti.

-- Cleaned up signed/unsigned inconsistencies, added typename keywords for compatibility with gcc.

-- Fixed a bug in Axiom 7 that allowed alignments involving points not on the paper

-- Added more description to the output of Axiom 6 to disambiguate cases where there are 
	multiple solutions for a given alignment.
	
-- Replaced Paper::Overlaps(), Paper::GetEndpoints() with Paper::InteriorOverlaps() and
	Paper::ClipLine(), which are cleaner implementations of the concept.
	
-- Created globals minAngleSine and minAspectRatio, which are used to filter out (respectively)
	RefMarks formed by the intersection of two nearly-parallel angles, and RefLines that require
	folding a long skinny flap near the edge of the paper.

Version 3.0b1 (5-6-03)

Version 3 is almost completely rewritten from version 2.1 and its predecessors.

-- I have implemented all 7 of the Huzita-Hatori Axioms, which are all the things you
	can do with a single crease.
	
-- Version 3 contains no duplicate lines or marks. Duplicates are avoided by a new scheme
	of storing objects that uses the C++ map<> class and distinct keys associated with each
	mark or line.
	
-- The combination of more axioms and elimination of duplication means that Version 3
	provides better accuracy than versions 1 or 2 with fewer creases. Nothing has a rank
	higher than 6 (2 fewer than version 2.1).
	
-- Version 3 also checks visibility of alignments and won't create an alignment that can't
	be made with opaque paper.
	
-- There are many switches and compiler-level custom settings that let you adjust the
	level of accuracy and the tradeoffs with speed and memory.

CONTACT INFORMATION

For comments, bugs, attaboys, etc., please contact me, Robert J. Lang, via this page:
http://www.langorigami.com/info/contact.php4.

*/