diff options
Diffstat (limited to 'lib/pure/basic2d.nim')
-rw-r--r-- | lib/pure/basic2d.nim | 212 |
1 files changed, 106 insertions, 106 deletions
diff --git a/lib/pure/basic2d.nim b/lib/pure/basic2d.nim index a344cd053..d18e73c16 100644 --- a/lib/pure/basic2d.nim +++ b/lib/pure/basic2d.nim @@ -20,20 +20,20 @@ import strutils ## ## # Create a matrix which first rotates, then scales and at last translates ## -## var m:TMatrix2d=rotate(DEG90) & scale(2.0) & move(100.0,200.0) +## var m:Matrix2d=rotate(DEG90) & scale(2.0) & move(100.0,200.0) ## ## # Create a 2d point at (100,0) and a vector (5,2) ## -## var pt:TPoint2d=point2d(100.0,0.0) +## var pt:Point2d=point2d(100.0,0.0) ## -## var vec:TVector2d=vector2d(5.0,2.0) +## var vec:Vector2d=vector2d(5.0,2.0) ## ## ## pt &= m # transforms pt in place ## -## var pt2:TPoint2d=pt & m #concatenates pt with m and returns a new point +## var pt2:Point2d=pt & m #concatenates pt with m and returns a new point ## -## var vec2:TVector2d=vec & m #concatenates vec with m and returns a new vector +## var vec2:Vector2d=vec & m #concatenates vec with m and returns a new vector const @@ -57,46 +57,46 @@ const ## used internally by DegToRad and RadToDeg type - TMatrix2d* = object + Matrix2d* = object ## Implements a row major 2d matrix, which means ## transformations are applied the order they are concatenated. ## The rightmost column of the 3x3 matrix is left out since normally ## not used for geometric transformations in 2d. ax*,ay*,bx*,by*,tx*,ty*:float - TPoint2d* = object + Point2d* = object ## Implements a non-homegeneous 2d point stored as ## an `x` coordinate and an `y` coordinate. x*,y*:float - TVector2d* = object + Vector2d* = object ## Implements a 2d **direction vector** stored as ## an `x` coordinate and an `y` coordinate. Direction vector means, ## that when transforming a vector with a matrix, the translational ## part of the matrix is ignored. x*,y*:float - +{.deprecated: [TMatrix2d: Matrix2d, TPoint2d: Point2d, TVector2d: Vector2d].} # Some forward declarations... -proc matrix2d*(ax,ay,bx,by,tx,ty:float):TMatrix2d {.noInit.} +proc matrix2d*(ax,ay,bx,by,tx,ty:float):Matrix2d {.noInit.} ## Creates a new matrix. ## `ax`,`ay` is the local x axis ## `bx`,`by` is the local y axis ## `tx`,`ty` is the translation -proc vector2d*(x,y:float):TVector2d {.noInit,inline.} +proc vector2d*(x,y:float):Vector2d {.noInit,inline.} ## Returns a new vector (`x`,`y`) -proc point2d*(x,y:float):TPoint2d {.noInit,inline.} +proc point2d*(x,y:float):Point2d {.noInit,inline.} ## Returns a new point (`x`,`y`) let - IDMATRIX*:TMatrix2d=matrix2d(1.0,0.0,0.0,1.0,0.0,0.0) + IDMATRIX*:Matrix2d=matrix2d(1.0,0.0,0.0,1.0,0.0,0.0) ## Quick access to an identity matrix - ORIGO*:TPoint2d=point2d(0.0,0.0) + ORIGO*:Point2d=point2d(0.0,0.0) ## Quick acces to point (0,0) - XAXIS*:TVector2d=vector2d(1.0,0.0) + XAXIS*:Vector2d=vector2d(1.0,0.0) ## Quick acces to an 2d x-axis unit vector - YAXIS*:TVector2d=vector2d(0.0,1.0) + YAXIS*:Vector2d=vector2d(0.0,1.0) ## Quick acces to an 2d y-axis unit vector @@ -116,21 +116,21 @@ proc safeArccos(v:float):float= template makeBinOpVector(s:expr)= ## implements binary operators + , - , * and / for vectors - proc s*(a,b:TVector2d):TVector2d {.inline,noInit.} = vector2d(s(a.x,b.x),s(a.y,b.y)) - proc s*(a:TVector2d,b:float):TVector2d {.inline,noInit.} = vector2d(s(a.x,b),s(a.y,b)) - proc s*(a:float,b:TVector2d):TVector2d {.inline,noInit.} = vector2d(s(a,b.x),s(a,b.y)) + proc s*(a,b:Vector2d):Vector2d {.inline,noInit.} = vector2d(s(a.x,b.x),s(a.y,b.y)) + proc s*(a:Vector2d,b:float):Vector2d {.inline,noInit.} = vector2d(s(a.x,b),s(a.y,b)) + proc s*(a:float,b:Vector2d):Vector2d {.inline,noInit.} = vector2d(s(a,b.x),s(a,b.y)) template makeBinOpAssignVector(s:expr)= ## implements inplace binary operators += , -= , /= and *= for vectors - proc s*(a:var TVector2d,b:TVector2d) {.inline.} = s(a.x,b.x) ; s(a.y,b.y) - proc s*(a:var TVector2d,b:float) {.inline.} = s(a.x,b) ; s(a.y,b) + proc s*(a:var Vector2d,b:Vector2d) {.inline.} = s(a.x,b.x) ; s(a.y,b.y) + proc s*(a:var Vector2d,b:float) {.inline.} = s(a.x,b) ; s(a.y,b) # *************************************** -# TMatrix2d implementation +# Matrix2d implementation # *************************************** -proc setElements*(t:var TMatrix2d,ax,ay,bx,by,tx,ty:float) {.inline.}= +proc setElements*(t:var Matrix2d,ax,ay,bx,by,tx,ty:float) {.inline.}= ## Sets arbitrary elements in an existing matrix. t.ax=ax t.ay=ay @@ -139,10 +139,10 @@ proc setElements*(t:var TMatrix2d,ax,ay,bx,by,tx,ty:float) {.inline.}= t.tx=tx t.ty=ty -proc matrix2d*(ax,ay,bx,by,tx,ty:float):TMatrix2d = +proc matrix2d*(ax,ay,bx,by,tx,ty:float):Matrix2d = result.setElements(ax,ay,bx,by,tx,ty) -proc `&`*(a,b:TMatrix2d):TMatrix2d {.noInit.} = #concatenate matrices +proc `&`*(a,b:Matrix2d):Matrix2d {.noInit.} = #concatenate matrices ## Concatenates matrices returning a new matrix. # | a.AX a.AY 0 | | b.AX b.AY 0 | @@ -157,34 +157,34 @@ proc `&`*(a,b:TMatrix2d):TMatrix2d {.noInit.} = #concatenate matrices a.tx * b.ay + a.ty * b.by + b.ty) -proc scale*(s:float):TMatrix2d {.noInit.} = +proc scale*(s:float):Matrix2d {.noInit.} = ## Returns a new scale matrix. result.setElements(s,0,0,s,0,0) -proc scale*(s:float,org:TPoint2d):TMatrix2d {.noInit.} = +proc scale*(s:float,org:Point2d):Matrix2d {.noInit.} = ## Returns a new scale matrix using, `org` as scale origin. result.setElements(s,0,0,s,org.x-s*org.x,org.y-s*org.y) -proc stretch*(sx,sy:float):TMatrix2d {.noInit.} = +proc stretch*(sx,sy:float):Matrix2d {.noInit.} = ## Returns new a stretch matrix, which is a ## scale matrix with non uniform scale in x and y. result.setElements(sx,0,0,sy,0,0) -proc stretch*(sx,sy:float,org:TPoint2d):TMatrix2d {.noInit.} = +proc stretch*(sx,sy:float,org:Point2d):Matrix2d {.noInit.} = ## Returns a new stretch matrix, which is a ## scale matrix with non uniform scale in x and y. ## `org` is used as stretch origin. result.setElements(sx,0,0,sy,org.x-sx*org.x,org.y-sy*org.y) -proc move*(dx,dy:float):TMatrix2d {.noInit.} = +proc move*(dx,dy:float):Matrix2d {.noInit.} = ## Returns a new translation matrix. result.setElements(1,0,0,1,dx,dy) -proc move*(v:TVector2d):TMatrix2d {.noInit.} = +proc move*(v:Vector2d):Matrix2d {.noInit.} = ## Returns a new translation matrix from a vector. result.setElements(1,0,0,1,v.x,v.y) -proc rotate*(rad:float):TMatrix2d {.noInit.} = +proc rotate*(rad:float):Matrix2d {.noInit.} = ## Returns a new rotation matrix, which ## represents a rotation by `rad` radians let @@ -192,7 +192,7 @@ proc rotate*(rad:float):TMatrix2d {.noInit.} = c=cos(rad) result.setElements(c,s,-s,c,0,0) -proc rotate*(rad:float,org:TPoint2d):TMatrix2d {.noInit.} = +proc rotate*(rad:float,org:Point2d):Matrix2d {.noInit.} = ## Returns a new rotation matrix, which ## represents a rotation by `rad` radians around ## the origin `org` @@ -201,7 +201,7 @@ proc rotate*(rad:float,org:TPoint2d):TMatrix2d {.noInit.} = c=cos(rad) result.setElements(c,s,-s,c,org.x+s*org.y-c*org.x,org.y-c*org.y-s*org.x) -proc mirror*(v:TVector2d):TMatrix2d {.noInit.} = +proc mirror*(v:Vector2d):Matrix2d {.noInit.} = ## Returns a new mirror matrix, mirroring ## around the line that passes through origo and ## has the direction of `v` @@ -220,7 +220,7 @@ proc mirror*(v:TVector2d):TMatrix2d {.noInit.} = xy2,-sqd, 0.0,0.0) -proc mirror*(org:TPoint2d,v:TVector2d):TMatrix2d {.noInit.} = +proc mirror*(org:Point2d,v:Vector2d):Matrix2d {.noInit.} = ## Returns a new mirror matrix, mirroring ## around the line that passes through `org` and ## has the direction of `v` @@ -241,20 +241,20 @@ proc mirror*(org:TPoint2d,v:TVector2d):TMatrix2d {.noInit.} = -proc skew*(xskew,yskew:float):TMatrix2d {.noInit.} = +proc skew*(xskew,yskew:float):Matrix2d {.noInit.} = ## Returns a new skew matrix, which has its ## x axis rotated `xskew` radians from the local x axis, and ## y axis rotated `yskew` radians from the local y axis result.setElements(cos(yskew),sin(yskew),-sin(xskew),cos(xskew),0,0) -proc `$`* (t:TMatrix2d):string {.noInit.} = +proc `$`* (t:Matrix2d):string {.noInit.} = ## Returns a string representation of the matrix return rtos(t.ax) & "," & rtos(t.ay) & "," & rtos(t.bx) & "," & rtos(t.by) & "," & rtos(t.tx) & "," & rtos(t.ty) -proc isUniform*(t:TMatrix2d,tol=1.0e-6):bool= +proc isUniform*(t:Matrix2d,tol=1.0e-6):bool= ## Checks if the transform is uniform, that is ## perpendicular axes of equal length, which means (for example) ## it cannot transform a circle into an ellipse. @@ -268,18 +268,18 @@ proc isUniform*(t:TMatrix2d,tol=1.0e-6):bool= return true return false -proc determinant*(t:TMatrix2d):float= +proc determinant*(t:Matrix2d):float= ## Computes the determinant of the matrix. #NOTE: equivalent with perp.dot product for two 2d vectors return t.ax*t.by-t.bx*t.ay -proc isMirroring* (m:TMatrix2d):bool= +proc isMirroring* (m:Matrix2d):bool= ## Checks if the `m` is a mirroring matrix, ## which means it will reverse direction of a curve transformed with it return m.determinant<0.0 -proc inverse*(m:TMatrix2d):TMatrix2d {.noInit.} = +proc inverse*(m:Matrix2d):Matrix2d {.noInit.} = ## Returns a new matrix, which is the inverse of the matrix ## If the matrix is not invertible (determinant=0), an EDivByZero ## will be raised. @@ -293,7 +293,7 @@ proc inverse*(m:TMatrix2d):TMatrix2d {.noInit.} = (m.bx*m.ty-m.by*m.tx)/d, (m.ay*m.tx-m.ax*m.ty)/d) -proc equals*(m1:TMatrix2d,m2:TMatrix2d,tol=1.0e-6):bool= +proc equals*(m1:Matrix2d,m2:Matrix2d,tol=1.0e-6):bool= ## Checks if all elements of `m1`and `m2` is equal within ## a given tolerance `tol`. return @@ -304,17 +304,17 @@ proc equals*(m1:TMatrix2d,m2:TMatrix2d,tol=1.0e-6):bool= abs(m1.tx-m2.tx)<=tol and abs(m1.ty-m2.ty)<=tol -proc `=~`*(m1,m2:TMatrix2d):bool= +proc `=~`*(m1,m2:Matrix2d):bool= ## Checks if `m1`and `m2` is approximately equal, using a ## tolerance of 1e-6. equals(m1,m2) -proc isIdentity*(m:TMatrix2d,tol=1.0e-6):bool= +proc isIdentity*(m:Matrix2d,tol=1.0e-6):bool= ## Checks is a matrix is approximately an identity matrix, ## using `tol` as tolerance for each element. return equals(m,IDMATRIX,tol) -proc apply*(m:TMatrix2d,x,y:var float,translate=false)= +proc apply*(m:Matrix2d,x,y:var float,translate=false)= ## Applies transformation `m` onto `x`,`y`, optionally ## using the translation part of the matrix. if translate: # positional style transform @@ -329,29 +329,29 @@ proc apply*(m:TMatrix2d,x,y:var float,translate=false)= # *************************************** -# TVector2d implementation +# Vector2d implementation # *************************************** -proc vector2d*(x,y:float):TVector2d = #forward decl. +proc vector2d*(x,y:float):Vector2d = #forward decl. result.x=x result.y=y -proc polarVector2d*(ang:float,len:float):TVector2d {.noInit.} = +proc polarVector2d*(ang:float,len:float):Vector2d {.noInit.} = ## Returns a new vector with angle `ang` and magnitude `len` result.x=cos(ang)*len result.y=sin(ang)*len -proc slopeVector2d*(slope:float,len:float):TVector2d {.noInit.} = +proc slopeVector2d*(slope:float,len:float):Vector2d {.noInit.} = ## Returns a new vector having slope (dy/dx) given by ## `slope`, and a magnitude of `len` let ang=arctan(slope) result.x=cos(ang)*len result.y=sin(ang)*len -proc len*(v:TVector2d):float {.inline.}= +proc len*(v:Vector2d):float {.inline.}= ## Returns the length of the vector. sqrt(v.x*v.x+v.y*v.y) -proc `len=`*(v:var TVector2d,newlen:float) {.noInit.} = +proc `len=`*(v:var Vector2d,newlen:float) {.noInit.} = ## Sets the length of the vector, keeping its angle. let fac=newlen/v.len @@ -369,25 +369,25 @@ proc `len=`*(v:var TVector2d,newlen:float) {.noInit.} = v.x*=fac v.y*=fac -proc sqrLen*(v:TVector2d):float {.inline.}= +proc sqrLen*(v:Vector2d):float {.inline.}= ## Computes the squared length of the vector, which is ## faster than computing the absolute length. v.x*v.x+v.y*v.y -proc angle*(v:TVector2d):float= +proc angle*(v:Vector2d):float= ## Returns the angle of the vector. ## (The counter clockwise plane angle between posetive x axis and `v`) result=arctan2(v.y,v.x) if result<0.0: result+=DEG360 -proc `$` *(v:TVector2d):string= +proc `$` *(v:Vector2d):string= ## String representation of `v` result=rtos(v.x) result.add(",") result.add(rtos(v.y)) -proc `&` *(v:TVector2d,m:TMatrix2d):TVector2d {.noInit.} = +proc `&` *(v:Vector2d,m:Matrix2d):Vector2d {.noInit.} = ## Concatenate vector `v` with a transformation matrix. ## Transforming a vector ignores the translational part ## of the matrix. @@ -399,7 +399,7 @@ proc `&` *(v:TVector2d,m:TMatrix2d):TVector2d {.noInit.} = result.y=v.x*m.ay+v.y*m.by -proc `&=`*(v:var TVector2d,m:TMatrix2d) {.inline.}= +proc `&=`*(v:var Vector2d,m:Matrix2d) {.inline.}= ## Applies transformation `m` onto `v` in place. ## Transforming a vector ignores the translational part ## of the matrix. @@ -412,7 +412,7 @@ proc `&=`*(v:var TVector2d,m:TMatrix2d) {.inline.}= v.x=newx -proc tryNormalize*(v:var TVector2d):bool= +proc tryNormalize*(v:var Vector2d):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. @@ -427,13 +427,13 @@ proc tryNormalize*(v:var TVector2d):bool= return true -proc normalize*(v:var TVector2d) {.inline.}= +proc normalize*(v:var Vector2d) {.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 transformNorm*(v:var TVector2d,t:TMatrix2d)= +proc transformNorm*(v:var Vector2d,t:Matrix2d)= ## Applies a normal direction transformation `t` 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 @@ -452,7 +452,7 @@ proc transformNorm*(v:var TVector2d,t:TMatrix2d)= v.y = (t.ax*v.y-t.bx*v.x)/d v.x = newx -proc transformInv*(v:var TVector2d,t:TMatrix2d)= +proc transformInv*(v:var Vector2d,t:Matrix2d)= ## Applies inverse of a transformation `t` to `v` in place. ## This is faster than creating an inverse matrix and apply() it. ## Transforming a vector ignores the translational part @@ -467,7 +467,7 @@ proc transformInv*(v:var TVector2d,t:TMatrix2d)= v.y = (t.ax*v.y-t.ay*v.x)/d v.x = newx -proc transformNormInv*(v:var TVector2d,t:TMatrix2d)= +proc transformNormInv*(v:var Vector2d,t:Matrix2d)= ## Applies an inverse normal direction transformation `t` onto `v` in place. ## This is faster than creating an inverse ## matrix and transformNorm(...) it. Transforming a vector ignores the @@ -484,25 +484,25 @@ proc transformNormInv*(v:var TVector2d,t:TMatrix2d)= v.y=t.by*v.y+t.bx*v.x v.x=newx -proc rotate90*(v:var TVector2d) {.inline.}= +proc rotate90*(v:var Vector2d) {.inline.}= ## Quickly rotates vector `v` 90 degrees counter clockwise, ## without using any trigonometrics. swap(v.x,v.y) v.x= -v.x -proc rotate180*(v:var TVector2d){.inline.}= +proc rotate180*(v:var Vector2d){.inline.}= ## Quickly rotates vector `v` 180 degrees counter clockwise, ## without using any trigonometrics. v.x= -v.x v.y= -v.y -proc rotate270*(v:var TVector2d) {.inline.}= +proc rotate270*(v:var Vector2d) {.inline.}= ## Quickly rotates vector `v` 270 degrees counter clockwise, ## without using any trigonometrics. swap(v.x,v.y) v.y= -v.y -proc rotate*(v:var TVector2d,rad:float) = +proc rotate*(v:var Vector2d,rad:float) = ## Rotates vector `v` `rad` radians in place. let s=sin(rad) @@ -511,18 +511,18 @@ proc rotate*(v:var TVector2d,rad:float) = v.y=c*v.y+s*v.x v.x=newx -proc scale*(v:var TVector2d,fac:float){.inline.}= +proc scale*(v:var Vector2d,fac:float){.inline.}= ## Scales vector `v` `rad` radians in place. v.x*=fac v.y*=fac -proc stretch*(v:var TVector2d,facx,facy:float){.inline.}= +proc stretch*(v:var Vector2d,facx,facy:float){.inline.}= ## Stretches vector `v` `facx` times horizontally, ## and `facy` times vertically. v.x*=facx v.y*=facy -proc mirror*(v:var TVector2d,mirrvec:TVector2d)= +proc mirror*(v:var Vector2d,mirrvec:Vector2d)= ## Mirrors vector `v` using `mirrvec` as mirror direction. let sqx=mirrvec.x*mirrvec.x @@ -539,7 +539,7 @@ proc mirror*(v:var TVector2d,mirrvec:TVector2d)= v.x=newx -proc `-` *(v:TVector2d):TVector2d= +proc `-` *(v:Vector2d):Vector2d= ## Negates a vector result.x= -v.x result.y= -v.y @@ -555,27 +555,27 @@ makeBinOpAssignVector(`*=`) makeBinOpAssignVector(`/=`) -proc dot*(v1,v2:TVector2d):float= +proc dot*(v1,v2:Vector2d):float= ## Computes the dot product of two vectors. ## Returns 0.0 if the vectors are perpendicular. return v1.x*v2.x+v1.y*v2.y -proc cross*(v1,v2:TVector2d):float= +proc cross*(v1,v2:Vector2d):float= ## Computes the cross product of two vectors, also called ## the 'perpendicular dot product' in 2d. Returns 0.0 if the vectors ## are parallel. return v1.x*v2.y-v1.y*v2.x -proc equals*(v1,v2:TVector2d,tol=1.0e-6):bool= +proc equals*(v1,v2:Vector2d,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 -proc `=~` *(v1,v2:TVector2d):bool= +proc `=~` *(v1,v2:Vector2d):bool= ## Checks if two vectors approximately equals with a ## hardcoded tolerance 1e-6 equals(v1,v2) -proc angleTo*(v1,v2:TVector2d):float= +proc angleTo*(v1,v2:Vector2d):float= ## Returns the smallest of the two possible angles ## between `v1` and `v2` in radians. var @@ -585,7 +585,7 @@ proc angleTo*(v1,v2:TVector2d):float= return 0.0 # zero length vector has zero angle to any other vector return safeArccos(dot(nv1,nv2)) -proc angleCCW*(v1,v2:TVector2d):float= +proc angleCCW*(v1,v2:Vector2d):float= ## Returns the counter clockwise plane angle from `v1` to `v2`, ## in range 0 - 2*PI let a=v1.angleTo(v2) @@ -593,7 +593,7 @@ proc angleCCW*(v1,v2:TVector2d):float= return a return DEG360-a -proc angleCW*(v1,v2:TVector2d):float= +proc angleCW*(v1,v2:Vector2d):float= ## Returns the clockwise plane angle from `v1` to `v2`, ## in range 0 - 2*PI let a=v1.angleTo(v2) @@ -601,7 +601,7 @@ proc angleCW*(v1,v2:TVector2d):float= return a return DEG360-a -proc turnAngle*(v1,v2:TVector2d):float= +proc turnAngle*(v1,v2:Vector2d):float= ## Returns the amount v1 should be rotated (in radians) to equal v2, ## in range -PI to PI let a=v1.angleTo(v2) @@ -609,7 +609,7 @@ proc turnAngle*(v1,v2:TVector2d):float= return -a return a -proc bisect*(v1,v2:TVector2d):TVector2d {.noInit.}= +proc bisect*(v1,v2:Vector2d):Vector2d {.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, @@ -645,24 +645,24 @@ proc bisect*(v1,v2:TVector2d):TVector2d {.noInit.}= # *************************************** -# TPoint2d implementation +# Point2d implementation # *************************************** -proc point2d*(x,y:float):TPoint2d = +proc point2d*(x,y:float):Point2d = result.x=x result.y=y -proc sqrDist*(a,b:TPoint2d):float= +proc sqrDist*(a,b:Point2d):float= ## Computes the squared distance between `a` and `b` let dx=b.x-a.x let dy=b.y-a.y result=dx*dx+dy*dy -proc dist*(a,b:TPoint2d):float {.inline.}= +proc dist*(a,b:Point2d):float {.inline.}= ## Computes the absolute distance between `a` and `b` result=sqrt(sqrDist(a,b)) -proc angle*(a,b:TPoint2d):float= +proc angle*(a,b:Point2d):float= ## Computes the angle of the vector `b`-`a` let dx=b.x-a.x let dy=b.y-a.y @@ -670,13 +670,13 @@ proc angle*(a,b:TPoint2d):float= if result<0: result += DEG360 -proc `$` *(p:TPoint2d):string= +proc `$` *(p:Point2d):string= ## String representation of `p` result=rtos(p.x) result.add(",") result.add(rtos(p.y)) -proc `&`*(p:TPoint2d,t:TMatrix2d):TPoint2d {.noInit,inline.} = +proc `&`*(p:Point2d,t:Matrix2d):Point2d {.noInit,inline.} = ## Concatenates a point `p` with a transform `t`, ## resulting in a new, transformed point. @@ -686,14 +686,14 @@ proc `&`*(p:TPoint2d,t:TMatrix2d):TPoint2d {.noInit,inline.} = result.x=p.x*t.ax+p.y*t.bx+t.tx result.y=p.x*t.ay+p.y*t.by+t.ty -proc `&=` *(p:var TPoint2d,t:TMatrix2d) {.inline.}= +proc `&=` *(p:var Point2d,t:Matrix2d) {.inline.}= ## Applies transformation `t` onto `p` in place. let newx=p.x*t.ax+p.y*t.bx+t.tx p.y=p.x*t.ay+p.y*t.by+t.ty p.x=newx -proc transformInv*(p:var TPoint2d,t:TMatrix2d){.inline.}= +proc transformInv*(p:var Point2d,t:Matrix2d){.inline.}= ## Applies the inverse of transformation `t` onto `p` in place. ## If the matrix is not invertable (determinant=0) , EDivByZero will ## be raised. @@ -710,48 +710,48 @@ proc transformInv*(p:var TPoint2d,t:TMatrix2d){.inline.}= p.x=newx -proc `+`*(p:TPoint2d,v:TVector2d):TPoint2d {.noInit,inline.} = +proc `+`*(p:Point2d,v:Vector2d):Point2d {.noInit,inline.} = ## 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 -proc `+=`*(p:var TPoint2d,v:TVector2d) {.noInit,inline.} = +proc `+=`*(p:var Point2d,v:Vector2d) {.noInit,inline.} = ## Adds a vector `v` to a point `p` in place. p.x+=v.x p.y+=v.y -proc `-`*(p:TPoint2d,v:TVector2d):TPoint2d {.noInit,inline.} = +proc `-`*(p:Point2d,v:Vector2d):Point2d {.noInit,inline.} = ## 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 -proc `-`*(p1,p2:TPoint2d):TVector2d {.noInit,inline.} = +proc `-`*(p1,p2:Point2d):Vector2d {.noInit,inline.} = ## Subtracts `p2`from `p1` resulting in a difference vector. result.x=p1.x-p2.x result.y=p1.y-p2.y -proc `-=`*(p:var TPoint2d,v:TVector2d) {.noInit,inline.} = +proc `-=`*(p:var Point2d,v:Vector2d) {.noInit,inline.} = ## Subtracts a vector `v` from a point `p` in place. p.x-=v.x p.y-=v.y -proc equals(p1,p2:TPoint2d,tol=1.0e-6):bool {.inline.}= +proc equals(p1,p2:Point2d,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 -proc `=~`*(p1,p2:TPoint2d):bool {.inline.}= +proc `=~`*(p1,p2:Point2d):bool {.inline.}= ## Checks if two vectors approximately equals with a ## hardcoded tolerance 1e-6 equals(p1,p2) -proc polar*(p:TPoint2d,ang,dist:float):TPoint2d {.noInit.} = +proc polar*(p:Point2d,ang,dist:float):Point2d {.noInit.} = ## Returns a point with a given angle and distance away from `p` result.x=p.x+cos(ang)*dist result.y=p.y+sin(ang)*dist -proc rotate*(p:var TPoint2d,rad:float)= +proc rotate*(p:var Point2d,rad:float)= ## Rotates a point in place `rad` radians around origo. let c=cos(rad) @@ -760,7 +760,7 @@ proc rotate*(p:var TPoint2d,rad:float)= p.y=p.y*c+p.x*s p.x=newx -proc rotate*(p:var TPoint2d,rad:float,org:TPoint2d)= +proc rotate*(p:var Point2d,rad:float,org:Point2d)= ## Rotates a point in place `rad` radians using `org` as ## center of rotation. let @@ -770,50 +770,50 @@ proc rotate*(p:var TPoint2d,rad:float,org:TPoint2d)= p.y=(p.y - org.y) * c + (p.x - org.x) * s + org.y p.x=newx -proc scale*(p:var TPoint2d,fac:float) {.inline.}= +proc scale*(p:var Point2d,fac:float) {.inline.}= ## Scales a point in place `fac` times with world origo as origin. p.x*=fac p.y*=fac -proc scale*(p:var TPoint2d,fac:float,org:TPoint2d){.inline.}= +proc scale*(p:var Point2d,fac:float,org:Point2d){.inline.}= ## Scales the point in place `fac` times with `org` as origin. p.x=(p.x - org.x) * fac + org.x p.y=(p.y - org.y) * fac + org.y -proc stretch*(p:var TPoint2d,facx,facy:float){.inline.}= +proc stretch*(p:var Point2d,facx,facy:float){.inline.}= ## Scales a point in place non uniformly `facx` and `facy` times with ## world origo as origin. p.x*=facx p.y*=facy -proc stretch*(p:var TPoint2d,facx,facy:float,org:TPoint2d){.inline.}= +proc stretch*(p:var Point2d,facx,facy:float,org:Point2d){.inline.}= ## Scales the point in place non uniformly `facx` and `facy` times with ## `org` as origin. p.x=(p.x - org.x) * facx + org.x p.y=(p.y - org.y) * facy + org.y -proc move*(p:var TPoint2d,dx,dy:float){.inline.}= +proc move*(p:var Point2d,dx,dy:float){.inline.}= ## Translates a point `dx`, `dy` in place. p.x+=dx p.y+=dy -proc move*(p:var TPoint2d,v:TVector2d){.inline.}= +proc move*(p:var Point2d,v:Vector2d){.inline.}= ## Translates a point with vector `v` in place. p.x+=v.x p.y+=v.y -proc sgnArea*(a,b,c:TPoint2d):float= +proc sgnArea*(a,b,c:Point2d):float= ## Computes the signed area of the triangle thru points `a`,`b` and `c` ## result>0.0 for counter clockwise triangle ## result<0.0 for clockwise triangle ## This is commonly used to determinate side of a point with respect to a line. return ((b.x - c.x) * (b.y - a.y)-(b.y - c.y) * (b.x - a.x))*0.5 -proc area*(a,b,c:TPoint2d):float= +proc area*(a,b,c:Point2d):float= ## Computes the area of the triangle thru points `a`,`b` and `c` return abs(sgnArea(a,b,c)) -proc closestPoint*(p:TPoint2d,pts:varargs[TPoint2d]):TPoint2d= +proc closestPoint*(p:Point2d,pts:varargs[Point2d]):Point2d= ## Returns a point selected from `pts`, that has the closest ## euclidean distance to `p` assert(pts.len>0) # must have at least one point |