##############################################################################
# ThanCad 0.0.9 "DoesSomething": 2dimensional CAD with raster support for engineers.
#
# Copyright (c) 2001-2009 Thanasis Stamos, August 23, 2009
# URL: http://thancad.sourceforge.net
# e-mail: cyberthanasis@excite.com
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details (www.gnu.org/licenses/gpl.html).
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
"""\
ThanCad 0.0.9 "DoesSomething": 2dimensional CAD with raster support for engineers.
This module defines various functions needed by other ThanCad's modules.
"""
from math import fabs
import p_ggen
from p_gmath import thanNear2,thanNear3
#############################################################################
###########################################anag##################################
class ThanId:
"""Class to return unique ids (e.g. for wxWindows windows).
Ids 0-99 are reserved. It seems that when ids are plain integers
or plain integers converted to strings with str(), Tkinter will
neither work, nor complain about it. A prefix with a letter is
a workaround."""
def __init__(self, id=20000, prefix="t"):
"Initialise seed."
self.id = id
self.prefix = prefix
def new(self, nids=1):
"Return an id so that id, id+1, id+2, ..., id+nids-1 are unique."
i = self.id
self.id += nids
return self.prefix + str(i)
#############################################################################
#############################################################################
class ThanRectCoorTransf:
"""Class to tranform rectangular cordinates.
A rectangle represents a coordinate system, that is the
coordinates of lower left corner (point 1) and the coordinates
of the upper right corner (point 2).
A "global" and a "local" rectangle are given. It is assumed the
point 1 of the global rectangle corresponds linearly to point 1
of local rectangle. The same for point 2.
This class computes the coefficients of the linear formulas used
to transform global coordinates to local, and the opposite.
Note that while in general the global coordinates xg2>xg1 and yg2>yg1,
the local coordinates usually xl2>xl1 and yl2<yl1.
"""
def __init__(self):
"Initialise transformation."
pass
def set(self, globalr, localr):
"Computes new coefs for converting formulas."
xg1, yg1, xg2, yg2 = globalr
xl1, yl1, xl2, yl2 = localr
(self.axg2l, self.bxg2l) = self.coef(xg1, xg2, xl1, xl2)
(self.ayg2l, self.byg2l) = self.coef(yg1, yg2, yl1, yl2)
(self.axl2g, self.bxl2g) = self.coef(xl1, xl2, xg1, xg2)
(self.ayl2g, self.byl2g) = self.coef(yl1, yl2, yg1, yg2)
def coef(self, xg1, xg2, xl1, xl2):
"""Returns the formula coefficients converting global to local.
xLocal = xl1 + (xl2-xl1)/(xg2-xg1) * (xGlobal-xg1) =
xl1 + B*(xGlobal-xg1) = xl1 - B*xg1 + B*xGlobal =
A + B*xGlobal
"""
assert xg1 != xg2, "Some window has 1 dimension zero!"
b = float(xl2-xl1) / float(xg2-xg1)
a = xl1 - b*xg1
return a, b
def global2Local(self, xg, yg):
"Transform global coordinates to local."
return self.axg2l + self.bxg2l * xg, self.ayg2l + self.byg2l * yg
def global2Locali(self, xg, yg):
"Transform global coordinates to local converting to integers."
return int(self.axg2l + self.bxg2l * xg + 0.5), int(self.ayg2l + self.byg2l * yg + 0.5)
def local2Global(self, xl, yl):
"Transform local coordinates to global."
return self.axl2g + self.bxl2g * xl, self.ayl2g + self.byl2g * yl
def global2LocalRel(self, xg, yg):
"Transform global size to local."
return self.bxg2l * xg, self.byg2l * yg
def global2LocalReli(self, xg, yg):
"Transform global size to local converting to integer."
return int(self.bxg2l * xg + 0.5), int(self.byg2l * yg + 0.5)
def local2GlobalRel(self, xl, yl):
"Transform local size to global."
return self.bxl2g * xl, self.byl2g * yl
#############################################################################
#############################################################################
def thanCleanLine2(c):
"Clean zero lengthed segments (in 2 dimensions) of a continuous multiline."
if len(c) < 2: return [list(c1) for c1 in c]
cn = [list(c[0])]
for c1 in c:
if thanNear2(cn[-1], c1): continue
cn.append(list(c1))
return cn
def thanCleanLine3(c):
"Clean zero lengthed segments (in 3 dimensions) of a continuous multiline."
if len(c) < 2: return [list(c1) for c1 in c]
cn = [list(c[0])]
for c1 in c:
if thanNear3(cn[-1], c1): continue
cn.append(list(c1))
return cn
#############################################################################
#############################################################################
def thanConfigFile(confname, appdir=".thancad"):
"Returns the path of confname, placing it into appdir."
import thanvar
if thanvar.Win32: f1 = "$windir"
else: f1 = "~"
f = p_ggen.path(f1).expand()
if f == f1: f = f.getcwd() # expand failed; use current directory as homedir
f = f / appdir
if f.exists():
if not f.isdir(): return None, f+" is not a directory."
else:
try: f.mkdir()
except OSError, why: return None, why
return f / confname, ""
#MODULE LEVEL CODE. IT IS EXECUTED ONLY ONCE
if __name__ == "__main__":
print __doc__
|