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
00029
00030
00031
00032
00033 import math
00034
00035
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
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
00075
00076
00077
00078
00079
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
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
00128
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())