updated basic2d, basic3d modules
This commit is contained in:
parent
d69e8f4de4
commit
a6211058c5
2 changed files with 25 additions and 25 deletions
|
|
@ -92,7 +92,7 @@ proc point2d*(x,y:float):TPoint2d {.noInit,inline.}
|
||||||
let
|
let
|
||||||
IDMATRIX*:TMatrix2d=matrix2d(1.0,0.0,0.0,1.0,0.0,0.0)
|
IDMATRIX*:TMatrix2d=matrix2d(1.0,0.0,0.0,1.0,0.0,0.0)
|
||||||
## Quick access to an identity matrix
|
## Quick access to an identity matrix
|
||||||
ORIGO*:TPoint2d=Point2d(0.0,0.0)
|
ORIGO*:TPoint2d=point2d(0.0,0.0)
|
||||||
## Quick acces to point (0,0)
|
## Quick acces to point (0,0)
|
||||||
XAXIS*:TVector2d=vector2d(1.0,0.0)
|
XAXIS*:TVector2d=vector2d(1.0,0.0)
|
||||||
## Quick acces to an 2d x-axis unit vector
|
## Quick acces to an 2d x-axis unit vector
|
||||||
|
|
@ -212,7 +212,7 @@ proc mirror*(v:TVector2d):TMatrix2d {.noInit.} =
|
||||||
xy2=v.x*v.y*2.0*nd
|
xy2=v.x*v.y*2.0*nd
|
||||||
sqd=nd*(sqx-sqy)
|
sqd=nd*(sqx-sqy)
|
||||||
|
|
||||||
if nd==inf or nd==neginf:
|
if nd==Inf or nd==NegInf:
|
||||||
return IDMATRIX #mirroring around a zero vector is arbitrary=>just use identity
|
return IDMATRIX #mirroring around a zero vector is arbitrary=>just use identity
|
||||||
|
|
||||||
result.setElements(
|
result.setElements(
|
||||||
|
|
@ -231,7 +231,7 @@ proc mirror*(org:TPoint2d,v:TVector2d):TMatrix2d {.noInit.} =
|
||||||
xy2=v.x*v.y*2.0*nd
|
xy2=v.x*v.y*2.0*nd
|
||||||
sqd=nd*(sqx-sqy)
|
sqd=nd*(sqx-sqy)
|
||||||
|
|
||||||
if nd==inf or nd==neginf:
|
if nd==Inf or nd==NegInf:
|
||||||
return IDMATRIX #mirroring around a zero vector is arbitrary=>just use identity
|
return IDMATRIX #mirroring around a zero vector is arbitrary=>just use identity
|
||||||
|
|
||||||
result.setElements(
|
result.setElements(
|
||||||
|
|
@ -285,7 +285,7 @@ proc inverse*(m:TMatrix2d):TMatrix2d {.noInit.} =
|
||||||
## will be raised.
|
## will be raised.
|
||||||
let d=m.determinant
|
let d=m.determinant
|
||||||
if d==0.0:
|
if d==0.0:
|
||||||
raise newException(EDivByZero,"Cannot invert a zero determinant matrix")
|
raise newException(DivByZeroError,"Cannot invert a zero determinant matrix")
|
||||||
|
|
||||||
result.setElements(
|
result.setElements(
|
||||||
m.by/d,-m.ay/d,
|
m.by/d,-m.ay/d,
|
||||||
|
|
@ -360,7 +360,7 @@ proc `len=`*(v:var TVector2d,newlen:float) {.noInit.} =
|
||||||
v.y=0.0
|
v.y=0.0
|
||||||
return
|
return
|
||||||
|
|
||||||
if fac==inf or fac==neginf:
|
if fac==Inf or fac==NegInf:
|
||||||
#to short for float accuracy
|
#to short for float accuracy
|
||||||
#do as good as possible:
|
#do as good as possible:
|
||||||
v.x=newlen
|
v.x=newlen
|
||||||
|
|
@ -431,7 +431,7 @@ proc normalize*(v:var TVector2d) {.inline.}=
|
||||||
## Modifies `v` to have a length of 1.0, keeping its angle.
|
## Modifies `v` to have a length of 1.0, keeping its angle.
|
||||||
## If `v` has zero length, an EDivByZero will be raised.
|
## If `v` has zero length, an EDivByZero will be raised.
|
||||||
if not tryNormalize(v):
|
if not tryNormalize(v):
|
||||||
raise newException(EDivByZero,"Cannot normalize zero length vector")
|
raise newException(DivByZeroError,"Cannot normalize zero length vector")
|
||||||
|
|
||||||
proc transformNorm*(v:var TVector2d,t:TMatrix2d)=
|
proc transformNorm*(v:var TVector2d,t:TMatrix2d)=
|
||||||
## Applies a normal direction transformation `t` onto `v` in place.
|
## Applies a normal direction transformation `t` onto `v` in place.
|
||||||
|
|
@ -447,7 +447,7 @@ proc transformNorm*(v:var TVector2d,t:TMatrix2d)=
|
||||||
# | | 0 0 1 | |
|
# | | 0 0 1 | |
|
||||||
let d=t.determinant
|
let d=t.determinant
|
||||||
if(d==0.0):
|
if(d==0.0):
|
||||||
raise newException(EDivByZero,"Matrix is not invertible")
|
raise newException(DivByZeroError,"Matrix is not invertible")
|
||||||
let newx = (t.by*v.x-t.ay*v.y)/d
|
let newx = (t.by*v.x-t.ay*v.y)/d
|
||||||
v.y = (t.ax*v.y-t.bx*v.x)/d
|
v.y = (t.ax*v.y-t.bx*v.x)/d
|
||||||
v.x = newx
|
v.x = newx
|
||||||
|
|
@ -461,7 +461,7 @@ proc transformInv*(v:var TVector2d,t:TMatrix2d)=
|
||||||
let d=t.determinant
|
let d=t.determinant
|
||||||
|
|
||||||
if(d==0.0):
|
if(d==0.0):
|
||||||
raise newException(EDivByZero,"Matrix is not invertible")
|
raise newException(DivByZeroError,"Matrix is not invertible")
|
||||||
|
|
||||||
let newx=(t.by*v.x-t.bx*v.y)/d
|
let newx=(t.by*v.x-t.bx*v.y)/d
|
||||||
v.y = (t.ax*v.y-t.ay*v.x)/d
|
v.y = (t.ax*v.y-t.ay*v.x)/d
|
||||||
|
|
@ -531,7 +531,7 @@ proc mirror*(v:var TVector2d,mirrvec:TVector2d)=
|
||||||
xy2=mirrvec.x*mirrvec.y*2.0*nd
|
xy2=mirrvec.x*mirrvec.y*2.0*nd
|
||||||
sqd=nd*(sqx-sqy)
|
sqd=nd*(sqx-sqy)
|
||||||
|
|
||||||
if nd==inf or nd==neginf:
|
if nd==Inf or nd==NegInf:
|
||||||
return #mirroring around a zero vector is arbitrary=>keep as is is fastest
|
return #mirroring around a zero vector is arbitrary=>keep as is is fastest
|
||||||
|
|
||||||
let newx=xy2*v.y+sqd*v.x
|
let newx=xy2*v.y+sqd*v.x
|
||||||
|
|
@ -703,7 +703,7 @@ proc transformInv*(p:var TPoint2d,t:TMatrix2d){.inline.}=
|
||||||
# | TX TY 1 |
|
# | TX TY 1 |
|
||||||
let d=t.determinant
|
let d=t.determinant
|
||||||
if d==0.0:
|
if d==0.0:
|
||||||
raise newException(EDivByZero,"Cannot invert a zero determinant matrix")
|
raise newException(DivByZeroError,"Cannot invert a zero determinant matrix")
|
||||||
let
|
let
|
||||||
newx= (t.bx*t.ty-t.by*t.tx+p.x*t.by-p.y*t.bx)/d
|
newx= (t.bx*t.ty-t.by*t.tx+p.x*t.by-p.y*t.bx)/d
|
||||||
p.y = -(t.ax*t.ty-t.ay*t.tx+p.x*t.ay-p.y*t.ax)/d
|
p.y = -(t.ax*t.ty-t.ay*t.tx+p.x*t.ay-p.y*t.ax)/d
|
||||||
|
|
@ -820,11 +820,11 @@ proc closestPoint*(p:TPoint2d,pts:varargs[TPoint2d]):TPoint2d=
|
||||||
|
|
||||||
var
|
var
|
||||||
bestidx=0
|
bestidx=0
|
||||||
bestdist=p.sqrdist(pts[0])
|
bestdist=p.sqrDist(pts[0])
|
||||||
curdist:float
|
curdist:float
|
||||||
|
|
||||||
for idx in 1..high(pts):
|
for idx in 1..high(pts):
|
||||||
curdist=p.sqrdist(pts[idx])
|
curdist=p.sqrDist(pts[idx])
|
||||||
if curdist<bestdist:
|
if curdist<bestdist:
|
||||||
bestidx=idx
|
bestidx=idx
|
||||||
bestdist=curdist
|
bestdist=curdist
|
||||||
|
|
@ -852,4 +852,4 @@ proc radToDeg*(rad:float):float {.inline.}=
|
||||||
## converts `rad` radians to degrees
|
## converts `rad` radians to degrees
|
||||||
rad * RAD2DEGCONST
|
rad * RAD2DEGCONST
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -220,7 +220,7 @@ proc rotate*(angle:float,axis:TVector3d):TMatrix3d {.noInit.}=
|
||||||
|
|
||||||
var normax=axis
|
var normax=axis
|
||||||
if not normax.tryNormalize: #simplifies matrix computation below a lot
|
if not normax.tryNormalize: #simplifies matrix computation below a lot
|
||||||
raise newException(EDivByZero,"Cannot rotate around zero length axis")
|
raise newException(DivByZeroError,"Cannot rotate around zero length axis")
|
||||||
|
|
||||||
let
|
let
|
||||||
cs=cos(angle)
|
cs=cos(angle)
|
||||||
|
|
@ -251,7 +251,7 @@ proc rotate*(angle:float,org:TPoint3d,axis:TVector3d):TMatrix3d {.noInit.}=
|
||||||
|
|
||||||
var normax=axis
|
var normax=axis
|
||||||
if not normax.tryNormalize: #simplifies matrix computation below a lot
|
if not normax.tryNormalize: #simplifies matrix computation below a lot
|
||||||
raise newException(EDivByZero,"Cannot rotate around zero length axis")
|
raise newException(DivByZeroError,"Cannot rotate around zero length axis")
|
||||||
|
|
||||||
let
|
let
|
||||||
u=normax.x
|
u=normax.x
|
||||||
|
|
@ -348,7 +348,7 @@ proc mirror*(planeperp:TVector3d):TMatrix3d {.noInit.}=
|
||||||
# https://en.wikipedia.org/wiki/Transformation_matrix
|
# https://en.wikipedia.org/wiki/Transformation_matrix
|
||||||
var n=planeperp
|
var n=planeperp
|
||||||
if not n.tryNormalize:
|
if not n.tryNormalize:
|
||||||
raise newException(EDivByZero,"Cannot mirror over a plane with a zero length normal")
|
raise newException(DivByZeroError,"Cannot mirror over a plane with a zero length normal")
|
||||||
|
|
||||||
let
|
let
|
||||||
a=n.x
|
a=n.x
|
||||||
|
|
@ -375,7 +375,7 @@ proc mirror*(org:TPoint3d,planeperp:TVector3d):TMatrix3d {.noInit.}=
|
||||||
# With some fiddling this becomes reasonably simple:
|
# With some fiddling this becomes reasonably simple:
|
||||||
var n=planeperp
|
var n=planeperp
|
||||||
if not n.tryNormalize:
|
if not n.tryNormalize:
|
||||||
raise newException(EDivByZero,"Cannot mirror over a plane with a zero length normal")
|
raise newException(DivByZeroError,"Cannot mirror over a plane with a zero length normal")
|
||||||
|
|
||||||
let
|
let
|
||||||
a=n.x
|
a=n.x
|
||||||
|
|
@ -448,7 +448,7 @@ proc inverse*(m:TMatrix3d):TMatrix3d {.noInit.}=
|
||||||
O19=m.bx*m.cy-m.by*m.cx
|
O19=m.bx*m.cy-m.by*m.cx
|
||||||
|
|
||||||
if det==0.0:
|
if det==0.0:
|
||||||
raise newException(EDivByZero,"Cannot normalize zero length vector")
|
raise newException(DivByZeroError,"Cannot normalize zero length vector")
|
||||||
|
|
||||||
result.setElements(
|
result.setElements(
|
||||||
(m.bw*O4+m.by*O3-m.bz*O2)/det , (-m.aw*O4-m.ay*O3+m.az*O2)/det,
|
(m.bw*O4+m.by*O3-m.bz*O2)/det , (-m.aw*O4-m.ay*O3+m.az*O2)/det,
|
||||||
|
|
@ -537,7 +537,7 @@ proc apply*(m:TMatrix3d, x,y,z:var float, translate=false)=
|
||||||
# ***************************************
|
# ***************************************
|
||||||
# TVector3d implementation
|
# TVector3d implementation
|
||||||
# ***************************************
|
# ***************************************
|
||||||
proc Vector3d*(x,y,z:float):TVector3d=
|
proc vector3d*(x,y,z:float):TVector3d=
|
||||||
result.x=x
|
result.x=x
|
||||||
result.y=y
|
result.y=y
|
||||||
result.z=z
|
result.z=z
|
||||||
|
|
@ -559,7 +559,7 @@ proc `len=`*(v:var TVector3d,newlen:float) {.noInit.} =
|
||||||
v.z=0.0
|
v.z=0.0
|
||||||
return
|
return
|
||||||
|
|
||||||
if fac==inf or fac==neginf:
|
if fac==Inf or fac==NegInf:
|
||||||
#to short for float accuracy
|
#to short for float accuracy
|
||||||
#do as good as possible:
|
#do as good as possible:
|
||||||
v.x=newlen
|
v.x=newlen
|
||||||
|
|
@ -670,7 +670,7 @@ proc normalize*(v:var TVector3d) {.inline.}=
|
||||||
## Modifies `v` to have a length of 1.0, keeping its angle.
|
## Modifies `v` to have a length of 1.0, keeping its angle.
|
||||||
## If `v` has zero length, an EDivByZero will be raised.
|
## If `v` has zero length, an EDivByZero will be raised.
|
||||||
if not tryNormalize(v):
|
if not tryNormalize(v):
|
||||||
raise newException(EDivByZero,"Cannot normalize zero length vector")
|
raise newException(DivByZeroError,"Cannot normalize zero length vector")
|
||||||
|
|
||||||
proc rotate*(vec:var TVector3d,angle:float,axis:TVector3d)=
|
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
|
||||||
|
|
@ -681,7 +681,7 @@ proc rotate*(vec:var TVector3d,angle:float,axis:TVector3d)=
|
||||||
|
|
||||||
var normax=axis
|
var normax=axis
|
||||||
if not normax.tryNormalize:
|
if not normax.tryNormalize:
|
||||||
raise newException(EDivByZero,"Cannot rotate around zero length axis")
|
raise newException(DivByZeroError,"Cannot rotate around zero length axis")
|
||||||
|
|
||||||
let
|
let
|
||||||
cs=cos(angle)
|
cs=cos(angle)
|
||||||
|
|
@ -842,9 +842,9 @@ proc bisect*(v1,v2:TVector3d):TVector3d {.noInit.}=
|
||||||
# there are actually inifinitely many bisectors, we select just
|
# there are actually inifinitely many bisectors, we select just
|
||||||
# one of them.
|
# one of them.
|
||||||
result=v1.cross(XAXIS)
|
result=v1.cross(XAXIS)
|
||||||
if result.sqrlen<1.0e-9:
|
if result.sqrLen<1.0e-9:
|
||||||
result=v1.cross(YAXIS)
|
result=v1.cross(YAXIS)
|
||||||
if result.sqrlen<1.0e-9:
|
if result.sqrLen<1.0e-9:
|
||||||
result=v1.cross(ZAXIS) # now we should be guaranteed to have succeeded
|
result=v1.cross(ZAXIS) # now we should be guaranteed to have succeeded
|
||||||
result.normalize
|
result.normalize
|
||||||
|
|
||||||
|
|
@ -853,7 +853,7 @@ proc bisect*(v1,v2:TVector3d):TVector3d {.noInit.}=
|
||||||
# ***************************************
|
# ***************************************
|
||||||
# TPoint3d implementation
|
# TPoint3d implementation
|
||||||
# ***************************************
|
# ***************************************
|
||||||
proc Point3d*(x,y,z:float):TPoint3d=
|
proc point3d*(x,y,z:float):TPoint3d=
|
||||||
result.x=x
|
result.x=x
|
||||||
result.y=y
|
result.y=y
|
||||||
result.z=z
|
result.z=z
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue