diff options
author | Araq <rumpf_a@web.de> | 2015-04-25 23:13:38 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2015-04-25 23:17:00 +0200 |
commit | e40b6678919ae659ee209e248dc3e4c627c6e6c2 (patch) | |
tree | 0d104aa4485369de157a2cfc67b4e8af28783192 | |
parent | d3fc6e1f285950d9cddb338206d553ff7baee7d5 (diff) | |
download | Nim-e40b6678919ae659ee209e248dc3e4c627c6e6c2.tar.gz |
fixes regression: overloading by 'var'
-rw-r--r-- | compiler/sigmatch.nim | 5 | ||||
-rw-r--r-- | lib/pure/basic3d.nim | 256 | ||||
-rw-r--r-- | tests/overload/tspec.nim | 10 |
3 files changed, 140 insertions, 131 deletions
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index aad6b590e..2eda33c14 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -159,7 +159,7 @@ proc sumGeneric(t: PType): int = inc result inc isvar of tyGenericInvocation, tyTuple: - result = ord(t.kind == tyGenericInvocation) + result += ord(t.kind == tyGenericInvocation) for i in 0 .. <t.len: result += t.sons[i].sumGeneric break of tyGenericParam, tyExpr, tyStatic, tyStmt, tyTypeDesc: break @@ -167,7 +167,8 @@ proc sumGeneric(t: PType): int = tyString, tyCString, tyInt..tyInt64, tyFloat..tyFloat128, tyUInt..tyUInt64: return isvar - else: return 0 + else: + return 0 #var ggDebug: bool diff --git a/lib/pure/basic3d.nim b/lib/pure/basic3d.nim index 18ebed67b..5a943dd05 100644 --- a/lib/pure/basic3d.nim +++ b/lib/pure/basic3d.nim @@ -16,33 +16,33 @@ import times ## Vectors are implemented as direction vectors, ie. when transformed with a matrix ## the translation part of matrix is ignored. The coordinate system used is ## right handed, because its compatible with 2d coordinate system (rotation around -## zaxis equals 2d rotation). +## zaxis equals 2d rotation). ## Operators `+` , `-` , `*` , `/` , `+=` , `-=` , `*=` and `/=` are implemented ## for vectors and scalars. ## ## ## Quick start example: -## +## ## # Create a matrix which first rotates, then scales and at last translates -## +## ## var m:TMatrix3d=rotate(PI,vector3d(1,1,2.5)) & scale(2.0) & move(100.0,200.0,300.0) -## +## ## # Create a 3d point at (100,150,200) and a vector (5,2,3) -## -## var pt:TPoint3d=point3d(100.0,150.0,200.0) -## +## +## var pt:TPoint3d=point3d(100.0,150.0,200.0) +## ## var vec:TVector3d=vector3d(5.0,2.0,3.0) -## -## +## +## ## pt &= m # transforms pt in place -## +## ## var pt2:TPoint3d=pt & m #concatenates pt with m and returns a new point -## +## ## var vec2:TVector3d=vec & m #concatenates vec with m and returns a new vector -type +type TMatrix3d* =object ## Implements a row major 3d matrix, which means ## transformations are applied the order they are concatenated. @@ -53,12 +53,12 @@ type ## [ tx ty tz tw ] ax*,ay*,az*,aw*, bx*,by*,bz*,bw*, cx*,cy*,cz*,cw*, tx*,ty*,tz*,tw*:float TPoint3d* = object - ## Implements a non-homegeneous 2d point stored as + ## Implements a non-homegeneous 2d point stored as ## an `x` , `y` and `z` coordinate. x*,y*,z*:float - TVector3d* = object - ## Implements a 3d **direction vector** stored as - ## an `x` , `y` and `z` coordinate. Direction vector means, + TVector3d* = object + ## Implements a 3d **direction vector** stored as + ## an `x` , `y` and `z` coordinate. Direction vector means, ## that when transforming a vector with a matrix, the translational ## part of the matrix is ignored. x*,y*,z*:float @@ -67,7 +67,7 @@ type # Some forward declarations proc matrix3d*(ax,ay,az,aw,bx,by,bz,bw,cx,cy,cz,cw,tx,ty,tz,tw:float):TMatrix3d {.noInit.} - ## Creates a new 4x4 3d transformation matrix. + ## Creates a new 4x4 3d transformation matrix. ## `ax` , `ay` , `az` is the local x axis. ## `bx` , `by` , `bz` is the local y axis. ## `cx` , `cy` , `cz` is the local z axis. @@ -76,7 +76,7 @@ proc vector3d*(x,y,z:float):TVector3d {.noInit,inline.} ## Returns a new 3d vector (`x`,`y`,`z`) proc point3d*(x,y,z:float):TPoint3d {.noInit,inline.} ## Returns a new 4d point (`x`,`y`,`z`) -proc tryNormalize*(v:var TVector3d):bool +proc tryNormalize*(v:var TVector3d):bool ## Modifies `v` to have a length of 1.0, keeping its angle. ## If `v` has zero length (and thus no angle), it is left unmodified and false is ## returned, otherwise true is returned. @@ -85,7 +85,7 @@ proc tryNormalize*(v:var TVector3d):bool let IDMATRIX*:TMatrix3d=matrix3d( - 1.0,0.0,0.0,0.0, + 1.0,0.0,0.0,0.0, 0.0,1.0,0.0,0.0, 0.0,0.0,1.0,0.0, 0.0,0.0,0.0,1.0) @@ -114,20 +114,20 @@ proc safeArccos(v:float):float= ## due to rounding issues return arccos(clamp(v,-1.0,1.0)) -template makeBinOpVector(s:expr)= +template makeBinOpVector(s:expr)= ## implements binary operators + , - , * and / for vectors - proc s*(a,b:TVector3d):TVector3d {.inline,noInit.} = + proc s*(a,b:TVector3d):TVector3d {.inline,noInit.} = vector3d(s(a.x,b.x),s(a.y,b.y),s(a.z,b.z)) - proc s*(a:TVector3d,b:float):TVector3d {.inline,noInit.} = + proc s*(a:TVector3d,b:float):TVector3d {.inline,noInit.} = vector3d(s(a.x,b),s(a.y,b),s(a.z,b)) - proc s*(a:float,b:TVector3d):TVector3d {.inline,noInit.} = + proc s*(a:float,b:TVector3d):TVector3d {.inline,noInit.} = vector3d(s(a,b.x),s(a,b.y),s(a,b.z)) - -template makeBinOpAssignVector(s:expr)= + +template makeBinOpAssignVector(s:expr)= ## implements inplace binary operators += , -= , /= and *= for vectors - proc s*(a:var TVector3d,b:TVector3d) {.inline.} = + proc s*(a:var TVector3d,b:TVector3d) {.inline.} = s(a.x,b.x) ; s(a.y,b.y) ; s(a.z,b.z) - proc s*(a:var TVector3d,b:float) {.inline.} = + proc s*(a:var TVector3d,b:float) {.inline.} = s(a.x,b) ; s(a.y,b) ; s(a.z,b) @@ -188,20 +188,20 @@ proc scale*(s:float):TMatrix3d {.noInit.} = proc scale*(s:float,org:TPoint3d):TMatrix3d {.noInit.} = ## Returns a new scaling matrix using, `org` as scale origin. - result.setElements(s,0,0,0, 0,s,0,0, 0,0,s,0, + result.setElements(s,0,0,0, 0,s,0,0, 0,0,s,0, org.x-s*org.x,org.y-s*org.y,org.z-s*org.z,1.0) proc stretch*(sx,sy,sz:float):TMatrix3d {.noInit.} = ## Returns new a stretch matrix, which is a ## scale matrix with non uniform scale in x,y and z. result.setElements(sx,0,0,0, 0,sy,0,0, 0,0,sz,0, 0,0,0,1) - + proc stretch*(sx,sy,sz:float,org:TPoint3d):TMatrix3d {.noInit.} = ## Returns a new stretch matrix, which is a ## scale matrix with non uniform scale in x,y and z. ## `org` is used as stretch origin. result.setElements(sx,0,0,0, 0,sy,0,0, 0,0,sz,0, org.x-sx*org.x,org.y-sy*org.y,org.z-sz*org.z,1) - + proc move*(dx,dy,dz:float):TMatrix3d {.noInit.} = ## Returns a new translation matrix. result.setElements(1,0,0,0, 0,1,0,0, 0,0,1,0, dx,dy,dz,1) @@ -235,7 +235,7 @@ proc rotate*(angle:float,axis:TVector3d):TMatrix3d {.noInit.}= uvomc=normax.x*normax.y*omc uwomc=normax.x*normax.z*omc vwomc=normax.y*normax.z*omc - + result.setElements( u2+(1.0-u2)*cs, uvomc+wsi, uwomc-vsi, 0.0, uvomc-wsi, v2+(1.0-v2)*cs, vwomc+usi, 0.0, @@ -248,11 +248,11 @@ proc rotate*(angle:float,org:TPoint3d,axis:TVector3d):TMatrix3d {.noInit.}= # see PDF document http://inside.mines.edu/~gmurray/ArbitraryAxisRotation/ArbitraryAxisRotation.pdf # for how this is computed - + var normax=axis if not normax.tryNormalize: #simplifies matrix computation below a lot raise newException(DivByZeroError,"Cannot rotate around zero length axis") - + let u=normax.x v=normax.y @@ -272,7 +272,7 @@ proc rotate*(angle:float,org:TPoint3d,axis:TVector3d):TMatrix3d {.noInit.}= uvomc=normax.x*normax.y*omc uwomc=normax.x*normax.z*omc vwomc=normax.y*normax.z*omc - + result.setElements( u2+(v2+w2)*cs, uvomc+wsi, uwomc-vsi, 0.0, uvomc-wsi, v2+(u2+w2)*cs, vwomc+usi, 0.0, @@ -305,7 +305,7 @@ proc rotateY*(angle:float):TMatrix3d {.noInit.}= 0,1,0,0, s,0,c,0, 0,0,0,1) - + proc rotateZ*(angle:float):TMatrix3d {.noInit.}= ## Creates a matrix that rotates around the z-axis with `angle` radians, ## which is also called a 'yaw' matrix. @@ -317,19 +317,19 @@ proc rotateZ*(angle:float):TMatrix3d {.noInit.}= -s,c,0,0, 0,0,1,0, 0,0,0,1) - + proc isUniform*(m:TMatrix3d,tol=1.0e-6):bool= - ## Checks if the transform is uniform, that is + ## Checks if the transform is uniform, that is ## perpendicular axes of equal length, which means (for example) ## it cannot transform a sphere into an ellipsoid. - ## `tol` is used as tolerance for both equal length comparison + ## `tol` is used as tolerance for both equal length comparison ## and perpendicular comparison. - + #dot product=0 means perpendicular coord. system, check xaxis vs yaxis and xaxis vs zaxis if abs(m.ax*m.bx+m.ay*m.by+m.az*m.bz)<=tol and # x vs y abs(m.ax*m.cx+m.ay*m.cy+m.az*m.cz)<=tol and #x vs z abs(m.bx*m.cx+m.by*m.cy+m.bz*m.cz)<=tol: #y vs z - + #subtract squared lengths of axes to check if uniform scaling: let sqxlen=(m.ax*m.ax+m.ay*m.ay+m.az*m.az) @@ -340,16 +340,16 @@ proc isUniform*(m:TMatrix3d,tol=1.0e-6):bool= return false - + proc mirror*(planeperp:TVector3d):TMatrix3d {.noInit.}= ## Creates a matrix that mirrors over the plane that has `planeperp` as normal, ## and passes through origo. `planeperp` does not need to be normalized. - + # https://en.wikipedia.org/wiki/Transformation_matrix var n=planeperp if not n.tryNormalize: raise newException(DivByZeroError,"Cannot mirror over a plane with a zero length normal") - + let a=n.x b=n.y @@ -357,7 +357,7 @@ proc mirror*(planeperp:TVector3d):TMatrix3d {.noInit.}= ab=a*b ac=a*c bc=b*c - + result.setElements( 1-2*a*a , -2*ab,-2*ac,0, -2*ab , 1-2*b*b, -2*bc, 0, @@ -376,7 +376,7 @@ proc mirror*(org:TPoint3d,planeperp:TVector3d):TMatrix3d {.noInit.}= var n=planeperp if not n.tryNormalize: raise newException(DivByZeroError,"Cannot mirror over a plane with a zero length normal") - + let a=n.x b=n.y @@ -390,7 +390,7 @@ proc mirror*(org:TPoint3d,planeperp:TVector3d):TMatrix3d {.noInit.}= tx=org.x ty=org.y tz=org.z - + result.setElements( 1-2*aa , -2*ab,-2*ac,0, -2*ab , 1-2*bb, -2*bc, 0, @@ -402,8 +402,8 @@ proc mirror*(org:TPoint3d,planeperp:TVector3d):TMatrix3d {.noInit.}= proc determinant*(m:TMatrix3d):float= ## Computes the determinant of matrix `m`. - - # This computation is gotten from ratsimp(optimize(determinant(m))) + + # This computation is gotten from ratsimp(optimize(determinant(m))) # in maxima CAS let O1=m.cx*m.tw-m.cw*m.tx @@ -423,10 +423,10 @@ proc inverse*(m:TMatrix3d):TMatrix3d {.noInit.}= ## Computes the inverse of matrix `m`. If the matrix ## determinant is zero, thus not invertible, a EDivByZero ## will be raised. - + # this computation comes from optimize(invert(m)) in maxima CAS - - let + + let det=m.determinant O2=m.cy*m.tw-m.cw*m.ty O3=m.cz*m.tw-m.cw*m.tz @@ -464,7 +464,7 @@ proc inverse*(m:TMatrix3d):TMatrix3d {.noInit.}= proc equals*(m1:TMatrix3d,m2:TMatrix3d,tol=1.0e-6):bool= ## Checks if all elements of `m1`and `m2` is equal within ## a given tolerance `tol`. - return + return abs(m1.ax-m2.ax)<=tol and abs(m1.ay-m2.ay)<=tol and abs(m1.az-m2.az)<=tol and @@ -486,11 +486,11 @@ proc `=~`*(m1,m2:TMatrix3d):bool= ## Checks if `m1` and `m2` is approximately equal, using a ## tolerance of 1e-6. equals(m1,m2) - + proc transpose*(m:TMatrix3d):TMatrix3d {.noInit.}= ## Returns the transpose of `m` result.setElements(m.ax,m.bx,m.cx,m.tx,m.ay,m.by,m.cy,m.ty,m.az,m.bz,m.cz,m.tz,m.aw,m.bw,m.cw,m.tw) - + proc getXAxis*(m:TMatrix3d):TVector3d {.noInit.}= ## Gets the local x axis of `m` result.x=m.ax @@ -509,26 +509,26 @@ proc getZAxis*(m:TMatrix3d):TVector3d {.noInit.}= result.y=m.cy result.z=m.cz - + proc `$`*(m:TMatrix3d):string= ## String representation of `m` - return rtos(m.ax) & "," & rtos(m.ay) & "," &rtos(m.az) & "," & rtos(m.aw) & - "\n" & rtos(m.bx) & "," & rtos(m.by) & "," &rtos(m.bz) & "," & rtos(m.bw) & - "\n" & rtos(m.cx) & "," & rtos(m.cy) & "," &rtos(m.cz) & "," & rtos(m.cw) & - "\n" & rtos(m.tx) & "," & rtos(m.ty) & "," &rtos(m.tz) & "," & rtos(m.tw) - + return rtos(m.ax) & "," & rtos(m.ay) & "," & rtos(m.az) & "," & rtos(m.aw) & + "\n" & rtos(m.bx) & "," & rtos(m.by) & "," & rtos(m.bz) & "," & rtos(m.bw) & + "\n" & rtos(m.cx) & "," & rtos(m.cy) & "," & rtos(m.cz) & "," & rtos(m.cw) & + "\n" & rtos(m.tx) & "," & rtos(m.ty) & "," & rtos(m.tz) & "," & rtos(m.tw) + proc apply*(m:TMatrix3d, x,y,z:var float, translate=false)= ## Applies transformation `m` onto `x` , `y` , `z` , optionally ## using the translation part of the matrix. - let + let oldx=x oldy=y oldz=z - + x=m.cx*oldz+m.bx*oldy+m.ax*oldx y=m.cy*oldz+m.by*oldy+m.ay*oldx z=m.cz*oldz+m.bz*oldy+m.az*oldx - + if translate: x+=m.tx y+=m.ty @@ -552,13 +552,13 @@ proc `len=`*(v:var TVector3d,newlen:float) {.noInit.} = ## an arbitrary vector of the requested length is returned. let fac=newlen/v.len - + if newlen==0.0: v.x=0.0 v.y=0.0 v.z=0.0 return - + if fac==Inf or fac==NegInf: #to short for float accuracy #do as good as possible: @@ -588,7 +588,7 @@ proc `&` *(v:TVector3d,m:TMatrix3d):TVector3d {.noInit.} = ## Concatenate vector `v` with a transformation matrix. ## Transforming a vector ignores the translational part ## of the matrix. - + # | AX AY AZ AW | # | X Y Z 1 | * | BX BY BZ BW | # | CX CY CZ CW | @@ -605,12 +605,12 @@ proc `&=` *(v:var TVector3d,m:TMatrix3d) {.noInit.} = ## Applies transformation `m` onto `v` in place. ## Transforming a vector ignores the translational part ## of the matrix. - + # | AX AY AZ AW | # | X Y Z 1 | * | BX BY BZ BW | # | CX CY CZ CW | # | 0 0 0 1 | - + let newx=m.cx*v.z+m.bx*v.y+m.ax*v.x newy=m.cy*v.z+m.by*v.y+m.ay*v.x @@ -620,38 +620,38 @@ proc `&=` *(v:var TVector3d,m:TMatrix3d) {.noInit.} = proc transformNorm*(v:var TVector3d,m:TMatrix3d)= ## Applies a normal direction transformation `m` onto `v` in place. - ## The resulting vector is *not* normalized. Transforming a vector ignores the - ## translational part of the matrix. If the matrix is not invertible + ## The resulting vector is *not* normalized. Transforming a vector ignores the + ## translational part of the matrix. If the matrix is not invertible ## (determinant=0), an EDivByZero will be raised. # transforming a normal is done by transforming # by the transpose of the inverse of the original matrix - + # Major reason this simple function is here is that this function can be optimized in the future, # (possibly by hardware) as well as having a consistent API with the 2d version. v&=transpose(inverse(m)) - + proc transformInv*(v:var TVector3d,m:TMatrix3d)= - ## Applies the inverse of `m` on vector `v`. Transforming a vector ignores - ## the translational part of the matrix. Transforming a vector ignores the + ## Applies the inverse of `m` on vector `v`. Transforming a vector ignores + ## the translational part of the matrix. Transforming a vector ignores the ## translational part of the matrix. ## If the matrix is not invertible (determinant=0), an EDivByZero ## will be raised. - + # Major reason this simple function is here is that this function can be optimized in the future, # (possibly by hardware) as well as having a consistent API with the 2d version. v&=m.inverse - + proc transformNormInv*(vec:var TVector3d,m:TMatrix3d)= ## Applies an inverse normal direction transformation `m` onto `v` in place. - ## This is faster than creating an inverse - ## matrix and transformNorm(...) it. Transforming a vector ignores the + ## This is faster than creating an inverse + ## matrix and transformNorm(...) it. Transforming a vector ignores the ## translational part of the matrix. - + # see vector2d:s equivalent for a deeper look how/why this works vec&=m.transpose -proc tryNormalize*(v:var TVector3d):bool= +proc tryNormalize*(v:var TVector3d):bool= ## Modifies `v` to have a length of 1.0, keeping its angle. ## If `v` has zero length (and thus no angle), it is left unmodified and false is ## returned, otherwise true is returned. @@ -663,26 +663,26 @@ proc tryNormalize*(v:var TVector3d):bool= v.x/=mag v.y/=mag v.z/=mag - + return true -proc normalize*(v:var TVector3d) {.inline.}= +proc normalize*(v:var TVector3d) {.inline.}= ## Modifies `v` to have a length of 1.0, keeping its angle. ## If `v` has zero length, an EDivByZero will be raised. if not tryNormalize(v): raise newException(DivByZeroError,"Cannot normalize zero length vector") proc rotate*(vec:var TVector3d,angle:float,axis:TVector3d)= - ## Rotates `vec` in place, with `angle` radians over `axis`, which passes + ## Rotates `vec` in place, with `angle` radians over `axis`, which passes ## through origo. # see PDF document http://inside.mines.edu/~gmurray/ArbitraryAxisRotation/ArbitraryAxisRotation.pdf # for how this is computed - + var normax=axis if not normax.tryNormalize: raise newException(DivByZeroError,"Cannot rotate around zero length axis") - + let cs=cos(angle) si=sin(angle) @@ -694,11 +694,11 @@ proc rotate*(vec:var TVector3d,angle:float,axis:TVector3d)= y=vec.y z=vec.z uxyzomc=(u*x+v*y+w*z)*omc - + vec.x=u*uxyzomc+x*cs+(v*z-w*y)*si vec.y=v*uxyzomc+y*cs+(w*x-u*z)*si vec.z=w*uxyzomc+z*cs+(u*y-v*x)*si - + proc scale*(v:var TVector3d,s:float)= ## Scales the vector in place with factor `s` v.x*=s @@ -713,12 +713,12 @@ proc stretch*(v:var TVector3d,sx,sy,sz:float)= proc mirror*(v:var TVector3d,planeperp:TVector3d)= ## Computes the mirrored vector of `v` over the plane - ## that has `planeperp` as normal direction. + ## that has `planeperp` as normal direction. ## `planeperp` does not need to be normalized. - + var n=planeperp n.normalize - + let x=v.x y=v.y @@ -729,7 +729,7 @@ proc mirror*(v:var TVector3d,planeperp:TVector3d)= ac=a*c ab=a*b bc=b*c - + v.x= -2*(ac*z+ab*y+a*a*x)+x v.y= -2*(bc*z+b*b*y+ab*x)+y v.z= -2*(c*c*z+bc*y+ac*x)+z @@ -740,7 +740,7 @@ proc `-` *(v:TVector3d):TVector3d= result.x= -v.x result.y= -v.y result.z= -v.z - + # declare templated binary operators makeBinOpVector(`+`) makeBinOpVector(`-`) @@ -752,7 +752,7 @@ makeBinOpAssignVector(`*=`) makeBinOpAssignVector(`/=`) proc dot*(v1,v2:TVector3d):float {.inline.}= - ## Computes the dot product of two vectors. + ## Computes the dot product of two vectors. ## Returns 0.0 if the vectors are perpendicular. return v1.x*v2.x+v1.y*v2.y+v1.z*v2.z @@ -769,12 +769,12 @@ proc cross*(v1,v2:TVector3d):TVector3d {.inline.}= proc equals*(v1,v2:TVector3d,tol=1.0e-6):bool= ## Checks if two vectors approximately equals with a tolerance. return abs(v2.x-v1.x)<=tol and abs(v2.y-v1.y)<=tol and abs(v2.z-v1.z)<=tol - + proc `=~` *(v1,v2:TVector3d):bool= - ## Checks if two vectors approximately equals with a + ## Checks if two vectors approximately equals with a ## hardcoded tolerance 1e-6 equals(v1,v2) - + proc angleTo*(v1,v2:TVector3d):float= ## Returns the smallest angle between v1 and v2, ## which is in range 0-PI @@ -801,7 +801,7 @@ proc arbitraryAxis*(norm:TVector3d):TMatrix3d {.noInit.}= ay=cross(norm,ax) ay.normalize() az=cross(ax,ay) - + result.setElements( ax.x,ax.y,ax.z,0.0, ay.x,ay.y,ay.z,0.0, @@ -811,20 +811,20 @@ proc arbitraryAxis*(norm:TVector3d):TMatrix3d {.noInit.}= proc bisect*(v1,v2:TVector3d):TVector3d {.noInit.}= ## Computes the bisector between v1 and v2 as a normalized vector. ## If one of the input vectors has zero length, a normalized version - ## of the other is returned. If both input vectors has zero length, + ## of the other is returned. If both input vectors has zero length, ## an arbitrary normalized vector `v1` is returned. var vmag1=v1.len vmag2=v2.len - - # zero length vector equals arbitrary vector, just change + + # zero length vector equals arbitrary vector, just change # magnitude to one to avoid zero division - if vmag1==0.0: + if vmag1==0.0: if vmag2==0: #both are zero length return any normalized vector return XAXIS vmag1=1.0 - if vmag2==0.0: vmag2=1.0 - + if vmag2==0.0: vmag2=1.0 + let x1=v1.x/vmag1 y1=v1.y/vmag1 @@ -832,14 +832,14 @@ proc bisect*(v1,v2:TVector3d):TVector3d {.noInit.}= x2=v2.x/vmag2 y2=v2.y/vmag2 z2=v2.z/vmag2 - + result.x=(x1 + x2) * 0.5 result.y=(y1 + y2) * 0.5 result.z=(z1 + z2) * 0.5 - + if not result.tryNormalize(): # This can happen if vectors are colinear. In this special case - # there are actually inifinitely many bisectors, we select just + # there are actually inifinitely many bisectors, we select just # one of them. result=v1.cross(XAXIS) if result.sqrLen<1.0e-9: @@ -857,14 +857,14 @@ proc point3d*(x,y,z:float):TPoint3d= result.x=x result.y=y result.z=z - + proc sqrDist*(a,b:TPoint3d):float= ## Computes the squared distance between `a`and `b` let dx=b.x-a.x let dy=b.y-a.y let dz=b.z-a.z result=dx*dx+dy*dy+dz*dz - + proc dist*(a,b:TPoint3d):float {.inline.}= ## Computes the absolute distance between `a`and `b` result=sqrt(sqrDist(a,b)) @@ -876,7 +876,7 @@ proc `$` *(p:TPoint3d):string= result.add(rtos(p.y)) result.add(",") result.add(rtos(p.z)) - + proc `&`*(p:TPoint3d,m:TMatrix3d):TPoint3d= ## Concatenates a point `p` with a transform `m`, ## resulting in a new, transformed point. @@ -893,18 +893,18 @@ proc `&=` *(p:var TPoint3d,m:TMatrix3d)= p.x=m.cx*z+m.bx*y+m.ax*x+m.tx p.y=m.cy*z+m.by*y+m.ay*x+m.ty p.z=m.cz*z+m.bz*y+m.az*x+m.tz - + proc transformInv*(p:var TPoint3d,m:TMatrix3d)= ## Applies the inverse of transformation `m` onto `p` in place. ## If the matrix is not invertable (determinant=0) , EDivByZero will ## be raised. - + # can possibly be more optimized in the future so use this function when possible p&=inverse(m) proc `+`*(p:TPoint3d,v:TVector3d):TPoint3d {.noInit,inline.} = - ## Adds a vector `v` to a point `p`, resulting + ## Adds a vector `v` to a point `p`, resulting ## in a new point. result.x=p.x+v.x result.y=p.y+v.y @@ -917,7 +917,7 @@ proc `+=`*(p:var TPoint3d,v:TVector3d) {.noInit,inline.} = p.z+=v.z proc `-`*(p:TPoint3d,v:TVector3d):TPoint3d {.noInit,inline.} = - ## Subtracts a vector `v` from a point `p`, resulting + ## Subtracts a vector `v` from a point `p`, resulting ## in a new point. result.x=p.x-v.x result.y=p.y-v.y @@ -933,37 +933,37 @@ proc `-=`*(p:var TPoint3d,v:TVector3d) {.noInit,inline.} = ## Subtracts a vector `v` from a point `p` in place. p.x-=v.x p.y-=v.y - p.z-=v.z + p.z-=v.z proc equals(p1,p2:TPoint3d,tol=1.0e-6):bool {.inline.}= ## Checks if two points approximately equals with a tolerance. return abs(p2.x-p1.x)<=tol and abs(p2.y-p1.y)<=tol and abs(p2.z-p1.z)<=tol proc `=~`*(p1,p2:TPoint3d):bool {.inline.}= - ## Checks if two vectors approximately equals with a + ## Checks if two vectors approximately equals with a ## hardcoded tolerance 1e-6 equals(p1,p2) proc rotate*(p:var TPoint3d,rad:float,axis:TVector3d)= - ## Rotates point `p` in place `rad` radians about an axis + ## Rotates point `p` in place `rad` radians about an axis ## passing through origo. - + var v=vector3d(p.x,p.y,p.z) v.rotate(rad,axis) # reuse this code here since doing the same thing and quite complicated p.x=v.x p.y=v.y p.z=v.z - + proc rotate*(p:var TPoint3d,angle:float,org:TPoint3d,axis:TVector3d)= - ## Rotates point `p` in place `rad` radians about an axis + ## Rotates point `p` in place `rad` radians about an axis ## passing through `org` - + # see PDF document http://inside.mines.edu/~gmurray/ArbitraryAxisRotation/ArbitraryAxisRotation.pdf # for how this is computed - + var normax=axis normax.normalize - + let cs=cos(angle) omc=1.0-cs @@ -987,17 +987,17 @@ proc rotate*(p:var TPoint3d,angle:float,org:TPoint3d,axis:TVector3d)= bv=b*v cw=c*w uxmvymwz=ux-vy-wz - + p.x=(a*(vv+ww)-u*(bv+cw-uxmvymwz))*omc + x*cs + (b*w+v*z-c*v-w*y)*si p.y=(b*(uu+ww)-v*(au+cw-uxmvymwz))*omc + y*cs + (c*u-a*w+w*x-u*z)*si p.z=(c*(uu+vv)-w*(au+bv-uxmvymwz))*omc + z*cs + (a*v+u*y-b*u-v*x)*si - + proc scale*(p:var TPoint3d,fac:float) {.inline.}= ## Scales a point in place `fac` times with world origo as origin. p.x*=fac p.y*=fac p.z*=fac - + proc scale*(p:var TPoint3d,fac:float,org:TPoint3d){.inline.}= ## Scales the point in place `fac` times with `org` as origin. p.x=(p.x - org.x) * fac + org.x @@ -1005,7 +1005,7 @@ proc scale*(p:var TPoint3d,fac:float,org:TPoint3d){.inline.}= p.z=(p.z - org.z) * fac + org.z proc stretch*(p:var TPoint3d,facx,facy,facz:float){.inline.}= - ## Scales a point in place non uniformly `facx` , `facy` , `facz` times + ## Scales a point in place non uniformly `facx` , `facy` , `facz` times ## with world origo as origin. p.x*=facx p.y*=facy @@ -1017,7 +1017,7 @@ proc stretch*(p:var TPoint3d,facx,facy,facz:float,org:TPoint3d){.inline.}= p.x=(p.x - org.x) * facx + org.x p.y=(p.y - org.y) * facy + org.y p.z=(p.z - org.z) * facz + org.z - + proc move*(p:var TPoint3d,dx,dy,dz:float){.inline.}= ## Translates a point `dx` , `dy` , `dz` in place. @@ -1033,7 +1033,7 @@ proc move*(p:var TPoint3d,v:TVector3d){.inline.}= proc area*(a,b,c:TPoint3d):float {.inline.}= ## Computes the area of the triangle thru points `a` , `b` and `c` - + # The area of a planar 3d quadliteral is the magnitude of the cross # product of two edge vectors. Taking this time 0.5 gives the triangle area. return cross(b-a,c-a).len*0.5 diff --git a/tests/overload/tspec.nim b/tests/overload/tspec.nim index 99966e93e..f2002a390 100644 --- a/tests/overload/tspec.nim +++ b/tests/overload/tspec.nim @@ -12,7 +12,9 @@ ref T 2 1 @[123, 2, 1] -Called!''' +Called! +merge with var +merge no var''' """ # Things that's even in the spec now! @@ -103,8 +105,14 @@ proc mget*[T](future: FutureVar[T]): var T = proc reset*[T](future: FutureVar[T]) = echo "Called!" +proc merge[T](x: Future[T]) = echo "merge no var" +proc merge[T](x: var Future[T]) = echo "merge with var" + when true: var foo = newFutureVar[string]() foo.mget() = "" foo.mget.add("Foobar") foo.reset() + var bar = newFuture[int]() + bar.merge # merge with var + merge(newFuture[int]()) # merge no var |