FilletArc.py

Go to the documentation of this file.
00001 """
00002 ***************************************************************************
00003 *   Copyright (c) 2010 Werner Mayer <wmayer[at]users.sourceforge.net>     *
00004 *                                                                         *
00005 *   This file is part of the FreeCAD CAx development system.              *
00006 *                                                                         *
00007 *   This program is free software; you can redistribute it and/or modify  *
00008 *   it under the terms of the GNU General Public License (GPL)            *
00009 *   as published by the Free Software Foundation; either version 2 of     *
00010 *   the License, or (at your option) any later version.                   *
00011 *   for detail see the LICENCE text file.                                 *
00012 *                                                                         *
00013 *   FreeCAD is distributed in the hope that it will be useful,            *
00014 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00015 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00016 *   GNU Library General Public License for more details.                  *
00017 *                                                                         *
00018 *   You should have received a copy of the GNU Library General Public     *
00019 *   License along with FreeCAD; if not, write to the Free Software        *
00020 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  *
00021 *   USA                                                                   *
00022 *                                                                         *
00023 ***************************************************************************
00024 """
00025 
00026 __author__ = "Werner Mayer <wmayer[at]users.sourceforge.net>"
00027 
00028 # Formulas:
00029 # M2 = P + b*r2 + t*u
00030 # S1 = (r2*M1 + r1*M2)/(r1+r2)
00031 # S2 = M2-b*r2
00032 
00033 import math
00034 
00035 # 3d vector class
00036 class Vector:
00037         def __init__(self,x,y,z):
00038                 self.x=x
00039                 self.y=y
00040                 self.z=z
00041         def add(self,vec):
00042                 return Vector(self.x+vec.x,self.y+vec.y,self.z+vec.z)
00043         def sub(self,vec):
00044                 return Vector(self.x-vec.x,self.y-vec.y,self.z-vec.z)
00045         def dot(self,vec):
00046                 return self.x*vec.x+self.y*vec.y+self.z*vec.z
00047         def mult(self,s):
00048                 return Vector(self.x*s,self.y*s,self.z*s)
00049         def cross(self,vec):
00050                 return Vector(
00051                 self.y * vec.z - self.z * vec.y,
00052                 self.z * vec.x - self.x * vec.z,
00053                 self.x * vec.y - self.y * vec.x)
00054         def length(self):
00055                 return math.sqrt(self.x*self.x+self.y*self.y+self.z*self.z)
00056         def norm(self):
00057                 l = self.length()
00058                 if l > 0:
00059                         self.x /= l
00060                         self.y /= l
00061                         self.z /= l
00062         def __repr__(self):
00063                 return "(%f,%f,%f)" % (self.x,self.y,self.z)
00064 
00065 # A signum function
00066 def sgn(val):
00067         if val > 0:
00068                 return 1
00069         elif val < 0:
00070                 return -1
00071         else:
00072                 return 0
00073 
00074 # M1  ... is the center of the arc
00075 # P   ... is the end point of the arc and start point of the line
00076 # Q   ..  is a second point on the line
00077 # N   ... is the normal of the plane where the arc and the line lie on, usually N=(0,0,1) 
00078 # r2  ... the fillet radius
00079 # ccw ... counter-clockwise means which part of the arc is given. ccw must be either True or False 
00080 def makeFilletArc(M1,P,Q,N,r2,ccw):
00081         u = Q.sub(P)
00082         v = P.sub(M1)
00083         if ccw:
00084                 b = u.cross(N)
00085         else:
00086                 b = N.cross(u)
00087         b.norm()
00088         
00089         uu = u.dot(u)
00090         uv = u.dot(v)
00091         r1 = v.length()
00092 
00093         # distinguish between internal and external fillets
00094         r2 *= sgn(uv);
00095 
00096         cc = 2.0 * r2 * (b.dot(v)-r1)
00097         dd = uv * uv - uu * cc
00098         if dd < 0:
00099                 raise Exception("Unable to caluclate intersection points")
00100         t1 = (-uv + math.sqrt(dd)) / uu 
00101         t2 = (-uv - math.sqrt(dd)) / uu
00102         
00103         if (abs(t1) < abs(t2)):
00104                 t = t1
00105         else:
00106                 t = t2
00107                 
00108         br2 = b.mult(r2)
00109         print br2
00110         ut = u.mult(t)
00111         print ut
00112         M2 = P.add(ut).add(br2)
00113         S1 = M1.mult(r2/(r1+r2)).add(M2.mult(r1/(r1+r2)))
00114         S2 = M2.sub(br2)
00115         
00116         return (S1,S2,M2)
00117 
00118         
00119         
00120 def test():
00121         from FreeCAD import Base
00122         import Part
00123 
00124         P1=Base.Vector(1,-5,0)
00125         P2=Base.Vector(-5,2,0)
00126         P3=Base.Vector(1,5,0)
00127         #Q=Base.Vector(5,10,0)
00128         #Q=Base.Vector(5,11,0)
00129         Q=Base.Vector(5,0,0)
00130         r2=3.0
00131         axis=Base.Vector(0,0,1)
00132         ccw=False
00133 
00134         arc=Part.ArcOfCircle(P1,P2,P3)
00135         C=arc.Center
00136         Part.show(Part.makeLine(P3,Q))
00137         Part.show(arc.toShape())
00138 
00139         (S1,S2,M2) = makeArc(Vector(C.x,C.y,C.z),Vector(P3.x,P3.y,P3.z),Vector(Q.x,Q.y,Q.z),Vector(axis.x,axis.y,axis.z),r2,ccw)
00140         circle=Part.Circle(Base.Vector(M2.x,M2.y,M2.z), Base.Vector(0,0,1), math.fabs(r2))
00141         Part.show(circle.toShape())

Generated on Wed Nov 23 19:00:14 2011 for FreeCAD by  doxygen 1.6.1