Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
K
kicad-source-mirror
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
Elphel
kicad-source-mirror
Commits
d53f6664
Commit
d53f6664
authored
Sep 19, 2011
by
Vladimir Ur
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
New draft for length.h
parent
a5a435f1
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
168 additions
and
643 deletions
+168
-643
length.h
include/length.h
+168
-643
No files found.
include/length.h
View file @
d53f6664
...
@@ -3,661 +3,186 @@
...
@@ -3,661 +3,186 @@
* @file length.h
* @file length.h
*/
*/
#ifndef UNITS_H_INCLUDED
/* sorry it is not styles correctly, i'll work on it further */
#define UNITS_H_INCLUDED 1
#include <math.h>
#ifndef LENGTH_H_INCLUDED
#include <wx/gdicmn.h>
#define LENGTH_H_INCLUDED 1
/**********************************************/
/*! I'm a physical length */
/**********************************************/
class
LENGTH
typedef
int
DEF_LENGTH_VALUE
;
{
private
:
template
<
typename
T
=
DEF_LENGTH_VALUE
,
int
P
=
1
>
class
LENGTH
;
enum
{
METER
=
1000000000
,
/* The ONLY constant connecting length to the real world */
};
int
m_Units
;
/*!
* The only constructor allowing direct input of numeric value
* in internal units. As this is not allowed in public, it's private.
* Length objects elsewhere are created indirectly
* @param units Length in internal units.
*/
LENGTH
(
int
units
)
{
m_Units
=
units
;
}
public
:
/*!
* Equality comparison of physical lengths.
* @param y length to compare
* @return lengths are equal
*/
bool
operator
==
(
const
LENGTH
y
)
const
{
return
m_Units
==
y
.
m_Units
;
}
/*!
* Non-equality comparison of physical lengths.
* @param y length to compare
* @return lengts are different
*/
bool
operator
!=
(
const
LENGTH
y
)
const
{
return
m_Units
!=
y
.
m_Units
;
}
/*!
* Order comparison of physical lengths.
* @param y length to compare
* @return one less than another
*/
bool
operator
<
(
const
LENGTH
y
)
const
{
return
m_Units
<
y
.
m_Units
;
}
/*!
* Order comparison of physical lengths.
* @param y length to compare
* @return one greater than another
*/
bool
operator
>
(
const
LENGTH
y
)
const
{
return
m_Units
>
y
.
m_Units
;
}
/*!
template
<
typename
T
>
class
LENGTH_UNITS
;
* Order comparison of physical lengths.
* @param y length to compare
* @return one less or equal than another
*/
bool
operator
<=
(
const
LENGTH
y
)
const
{
return
m_Units
<=
y
.
m_Units
;
}
/*!
template
<
typename
T
,
int
P
>
struct
LENGTH_TRAITS
{
* Order comparison of physical lengths.
typedef
LENGTH
<
T
,
P
>
flat
;
* @param y length to compare
};
* @return one greater or equal than another
*/
bool
operator
>=
(
const
LENGTH
y
)
const
{
return
m_Units
>=
y
.
m_Units
;
}
/*!
* Sum of two physical lengths. Only another length can be added.
* @param y length to add
* @return result of addition
*/
const
LENGTH
operator
+
(
const
LENGTH
y
)
const
{
return
LENGTH
(
m_Units
+
y
.
m_Units
);
}
/*!
* Add a length inplace
* @param y length to add
* @return result of addition
*/
LENGTH
&
operator
+=
(
const
LENGTH
y
)
{
m_Units
+=
y
.
m_Units
;
return
*
this
;
}
/*!
* Differece of two physical lengths. Only another length can be subtracted.
* @param y length to subtract
* @return result of subtraction
*/
const
LENGTH
operator
-
(
const
LENGTH
y
)
const
{
return
LENGTH
(
m_Units
-
y
.
m_Units
);
}
/*!
* Subtract a length inplace
* @param y length to add
* @return result of addition
*/
LENGTH
&
operator
-=
(
const
LENGTH
y
)
{
m_Units
-=
y
.
m_Units
;
return
*
this
;
}
/*!
* Negation of length.
* @return length negated
*/
const
LENGTH
operator
-
(
void
)
const
{
return
LENGTH
(
-
m_Units
);
}
/*!
* Scale length to rational number, given numerator and denominator.
* This is done without overflow or precision loss unlike dealing
* with * / and floating point.
* @param mul numerator, length is multiplied by this value
* @param div denominator. length is divided by this value
* @return scaled length
*/
const
LENGTH
byRatio
(
int
mul
,
int
div
)
const
{
return
LENGTH
(
(
int
)(
(
long
long
)
m_Units
*
mul
/
div
)
);
}
/*!
* Scale length to rational number inplace.
* @param mul numerator, length is multiplied by this value
* @param div denominator. length is divided by this value
* @return scaled length
*/
LENGTH
&
setByRatio
(
int
mul
,
int
div
)
{
m_Units
=
(
int
)(
(
long
long
)
m_Units
*
mul
/
div
);
return
*
this
;
}
/*!
* Multiplies length by integer number.
* @param y factor
* @return scaled length
*/
const
LENGTH
operator
*
(
int
y
)
const
{
return
LENGTH
(
m_Units
*
y
);
}
/*!
template
<
typename
T
>
struct
LENGTH_TRAITS
<
T
,
0
>
{
* Multiply a length inplace
typedef
T
flat
;
* @param y factor
};
* @return scaled length
*/
LENGTH
&
operator
*=
(
int
y
)
{
m_Units
*=
y
;
return
*
this
;
}
/*!
template
<
typename
T
,
int
P
>
class
LENGTH
{
* Multiplies length by floating point.
friend
class
LENGTH_UNITS
<
T
>
;
* @param y factor
friend
class
LENGTH_TRAITS
<
T
,
P
>
;
* @return scaled length
template
<
typename
Y
,
int
R
>
friend
class
LENGTH
;
*/
protected
:
const
LENGTH
operator
*
(
double
y
)
const
{
return
LENGTH
(
(
int
)(
m_Units
*
y
)
);
}
/*!
T
m_U
;
* Multiply a length inplace
LENGTH
(
T
units
)
:
m_U
(
units
)
{
* @param y factor
* @return scaled length
*/
LENGTH
&
operator
*=
(
double
y
)
{
m_Units
*=
y
;
return
*
this
;
}
}
static
T
RawValue
(
const
LENGTH
<
T
,
P
>
&
x
)
{
/*!
return
x
.
m_U
;
* Multiplies integer by length ( like abowe with args swapped ).
* @param x factor
* @param y length
* @return scaled length
*/
const
LENGTH
friend
operator
*
(
int
x
,
const
LENGTH
y
)
{
return
y
*
x
;
}
}
static
T
RawValue
(
const
T
&
x
)
{
/*!
return
x
;
* Multiplies floating point by length ( like abowe with args swapped ).
* @param x factor
* @param y length
* @return scaled length
*/
const
LENGTH
friend
operator
*
(
double
x
,
const
LENGTH
y
)
{
return
y
*
x
;
}
}
public
:
/*!
typedef
LENGTH
<
T
,
P
>
flat
;
* Divides length by integer number.
typedef
T
value_type
;
* @param y divider
enum
{
* @return scaled length
dimension
=
P
*/
};
const
LENGTH
operator
/
(
int
y
)
const
LENGTH
(
const
LENGTH
<
T
,
P
>
&
orig
)
:
m_U
(
orig
.
m_U
)
{
{
return
LENGTH
(
m_Units
/
y
);
}
}
LENGTH
(
void
)
:
m_U
()
{
/*!
* Divide a length inplace
* @param y divider
* @return scaled length
*/
LENGTH
&
operator
/=
(
int
y
)
{
m_Units
/=
y
;
return
*
this
;
}
}
/*!
static
LENGTH
<
T
,
P
>
zero
(
void
)
{
* Divides length by floating point.
return
T
(
0
);
* @param y divider
* @return scaled length
*/
const
LENGTH
operator
/
(
double
y
)
const
{
return
LENGTH
(
(
long
long
)(
m_Units
/
y
)
);
}
}
/*!
LENGTH
<
T
,
P
>
&
operator
=
(
const
LENGTH
<
T
,
P
>
&
y
)
{
* Divide a length inplace
this
->
m_U
=
y
.
m_U
;
* @param y divider
* @return scaled length
*/
LENGTH
&
operator
/=
(
double
y
)
{
m_Units
/=
y
;
return
*
this
;
return
*
this
;
}
}
template
<
typename
Y
>
/*!
operator
LENGTH
<
Y
,
P
>
(
void
)
{
* Gets ratio of two lengths.
return
this
->
m_U
;
* It is usable to get number of length units in length by
* division of length by length unit ( See length units below ).
* @param y base length
* @return scaled length
*/
double
operator
/
(
const
LENGTH
y
)
const
{
return
(
double
)
m_Units
/
y
.
m_Units
;
}
}
/*************************/
/*!
/* comparisons and tests */
* Gets integer ( unlike operator / ) ratio of two lengths.
/*************************/
* It is usable to get number of length units in length by
bool
operator
==
(
const
LENGTH
<
T
,
P
>
y
)
const
{
* division of length by length unit ( See length units below ).
return
m_U
==
y
.
m_U
;
* @param y base length
* @return scaled length
*/
int
idiv
(
const
LENGTH
y
)
const
{
return
(
int
)(
m_Units
/
y
.
m_Units
);
}
}
bool
operator
!=
(
const
LENGTH
<
T
,
P
>
y
)
const
{
/*!
return
m_U
!=
y
.
m_U
;
* Zero.
* @return Zero length
*/
static
const
LENGTH
zero
(
void
)
{
return
LENGTH
(
0
);
}
/*!
* The metre unit.
* @return One metre length
*/
static
const
LENGTH
metre
(
void
)
{
return
LENGTH
(
METER
);
}
}
bool
operator
<
(
const
LENGTH
<
T
,
P
>
y
)
const
{
/*!
return
m_U
<
y
.
m_U
;
* The millimetre unit.
* @return One millimetre length
*/
static
const
LENGTH
millimetre
(
void
)
{
return
LENGTH
(
METER
/
1000
);
}
}
bool
operator
>=
(
const
LENGTH
<
T
,
P
>
y
)
const
{
/*!
return
m_U
>=
y
.
m_U
;
* The inch unit.
* @return One inch length
*/
static
const
LENGTH
inch
(
void
)
{
return
LENGTH
(
METER
/
10000
*
254
);
// ensure it's done without precision loss
}
}
bool
operator
>
(
const
LENGTH
<
T
,
P
>
y
)
const
{
/*!
return
m_U
>
y
.
m_U
;
* The mil unit.
* @return One mil length
*/
static
const
LENGTH
mil
(
void
)
{
return
inch
()
/
1000
;
}
}
bool
operator
<=
(
const
LENGTH
<
T
,
P
>
y
)
const
{
/*!
return
m_U
<=
y
.
m_U
;
* Hypotenuse of a triangle with two given katheti.
* @param y another kathetus
* @return hypothenuse
*/
const
LENGTH
hypotenuse
(
LENGTH
y
)
const
{
return
LENGTH
(
(
int
)
sqrt
(
(
(
double
)
m_Units
*
m_Units
+
(
double
)
y
.
m_Units
*
y
.
m_Units
)
)
);
}
}
bool
operator
!
(
void
)
const
{
/*!
return
!
m_U
;
* Another kathetus of a triangle with given hypothenuse and kathetus.
* @param y kathetus
* @return another kathetus
*/
const
LENGTH
kathetus
(
LENGTH
y
)
const
{
return
LENGTH
(
(
int
)
sqrt
(
(
(
double
)
m_Units
*
m_Units
-
(
double
)
y
.
m_Units
*
y
.
m_Units
)
)
);
}
}
/*************************/
};
/* basic arithmetic */
/*************************/
/**********************************************/
LENGTH
<
T
,
P
>
operator
-
(
void
)
const
{
/*! I'm a point/vector in a physical 2D plane */
return
LENGTH
<
T
,
P
>
(
-
this
->
m_U
);
/**********************************************/
class
LENGTH_XY
{
private
:
LENGTH
m_X
,
m_Y
;
public
:
/*!
* One given x and y coords of type LENGTH
* @param x coordinate
* @param y coordinate
*/
LENGTH_XY
(
const
LENGTH
x
,
const
LENGTH
y
)
:
m_X
(
x
),
m_Y
(
y
)
{
}
}
LENGTH
<
T
,
P
>
operator
-
(
const
LENGTH
<
T
,
P
>
y
)
const
{
/*!
return
m_U
-
y
.
m_U
;
* A point ( or vector ) given x and y multiplies of specified unit.
* Given just for a convenience, you can use ( x*unit, y*unit ) instead.
* @param x coordinate factor
* @param y coordinate factor
* @param unit the unit
*/
LENGTH_XY
(
int
x
,
int
y
,
const
LENGTH
unit
)
:
m_X
(
unit
*
x
),
m_Y
(
unit
*
y
)
{
}
}
LENGTH
<
T
,
P
>
operator
+
(
const
LENGTH
<
T
,
P
>
y
)
const
{
/*!
return
m_U
+
y
.
m_U
;
* A point ( or vector ) given wxPoint and unit
* @param x wxPoint
* @param unit the unit
*/
LENGTH_XY
(
wxPoint
x
,
const
LENGTH
unit
)
:
m_X
(
unit
*
x
.
x
),
m_Y
(
unit
*
x
.
y
)
{
}
}
template
<
int
R
>
/*!
typename
LENGTH_TRAITS
<
T
,
P
+
R
>::
flat
operator
*
(
const
LENGTH
<
T
,
R
>
&
y
)
const
{
* A point ( or vector ) given wxRealPoint and unit
return
m_U
*
y
.
m_U
;
* @param x wxRealPoint
* @param unit the unit
*/
LENGTH_XY
(
wxRealPoint
x
,
const
LENGTH
unit
)
:
m_X
(
unit
*
x
.
x
),
m_Y
(
unit
*
x
.
y
)
{
}
}
LENGTH
<
T
,
P
>
operator
*
(
const
T
&
y
)
const
{
/*!
return
m_U
*
y
;
* x coordinate
* @return x coordinate
*/
const
LENGTH
x
(
void
)
const
{
return
m_X
;
}
}
LENGTH
<
T
,
P
>
friend
operator
*
(
const
T
&
y
,
const
LENGTH
<
T
,
P
>
&
x
)
{
/*!
return
x
.
m_U
*
y
;
* y coordinate
* @return y coordinate
*/
const
LENGTH
y
(
void
)
const
{
return
m_Y
;
}
}
/*!
template
<
int
R
>
* Absoulte value / length
typename
LENGTH_TRAITS
<
T
,
P
-
R
>::
flat
operator
/
(
const
LENGTH
<
T
,
R
>
&
y
)
const
{
* @return absolute value
return
m_U
/
y
.
m_U
;
*/
const
LENGTH
abs
(
void
)
const
{
return
m_X
.
hypotenuse
(
m_Y
);
}
}
LENGTH
<
T
,
P
>
operator
/
(
const
T
&
y
)
const
{
/*!
return
m_U
/
y
;
* Equality comparison of vectors.
* @param y vectors to compare
* @return vectors are equal
*/
bool
operator
==
(
const
LENGTH_XY
y
)
const
{
return
m_X
==
y
.
m_X
&&
m_Y
==
y
.
m_Y
;
}
}
LENGTH
<
T
,
-
P
>
friend
operator
/
(
const
T
&
y
,
const
LENGTH
<
T
,
P
>
&
x
)
{
/*!
return
y
/
x
.
m_U
;
* Non-equality comparison of vectors.
* @param y vectors to compare
* @return vectors are different
*/
bool
operator
!=
(
const
LENGTH_XY
y
)
const
{
return
m_X
!=
y
.
m_X
||
m_Y
!=
y
.
m_Y
;
}
}
/*!
friend
LENGTH
<
T
,
P
>
sqrt
(
LENGTH
<
T
,
P
*
2
>
y
)
{
* Sum of two vectors ( or a point translated by vector )
return
sqrt
(
y
.
m_U
);
* @param y vector to add
* @return result of addition
*/
const
LENGTH_XY
operator
+
(
const
LENGTH_XY
y
)
const
{
return
LENGTH_XY
(
m_X
+
y
.
m_X
,
m_Y
+
y
.
m_Y
);
}
}
friend
LENGTH
<
T
,
P
>
cbrt
(
LENGTH
<
T
,
P
*
3
>
y
)
{
/*!
return
cbrt
(
y
.
m_U
);
* Translate a vector inplace
* @param y vector to add
* @return result of addition
*/
LENGTH_XY
&
operator
+=
(
const
LENGTH_XY
y
)
{
m_X
+=
y
.
m_X
;
m_Y
+=
y
.
m_Y
;
return
*
this
;
}
}
/*************************/
/*!
/* assignment arithmetic */
* Difference of two vectors ( or a point translated by vector in reverse direction ).
/*************************/
* @param y vector to subtract
LENGTH
<
T
,
P
>&
operator
-=
(
const
LENGTH
<
T
,
P
>
y
)
{
* @return result of subtraction
return
m_U
-=
y
.
m_U
;
*/
const
LENGTH_XY
operator
-
(
const
LENGTH_XY
y
)
const
{
return
LENGTH_XY
(
m_X
-
y
.
m_X
,
m_Y
-
y
.
m_Y
);
}
}
LENGTH
<
T
,
P
>&
operator
+=
(
const
LENGTH
<
T
,
P
>
y
)
{
/*!
return
m_U
+=
y
.
m_U
;
* Translate a vector inplace in opposite direction
* @param y vector to subtract
* @return result of subtraction
*/
LENGTH_XY
&
operator
-=
(
const
LENGTH_XY
y
)
{
m_X
-=
y
.
m_X
;
m_Y
-=
y
.
m_Y
;
return
*
this
;
}
}
LENGTH
<
T
,
P
>&
operator
*=
(
const
T
y
)
{
/*!
return
m_U
*=
y
;
* Vector with reverse direction.
* @return reverse direction vector
*/
const
LENGTH_XY
operator
-
(
void
)
const
{
return
LENGTH_XY
(
-
m_X
,
-
m_Y
);
}
}
LENGTH
<
T
,
P
>&
operator
/=
(
const
T
y
)
{
/*!
return
m_U
/=
y
;
* Scale vector to rational number, given numerator and denominator.
* This is done without overflow or precision loss unlike dealing
* with * / and floating point.
* @param mul numerator ( length is multiplied by this value )
* @param div denominator ( length is divided by this value )
* @return scaled vector
*/
const
LENGTH_XY
byRatio
(
int
mul
,
int
div
)
{
return
LENGTH_XY
(
m_X
.
byRatio
(
mul
,
div
),
m_Y
.
byRatio
(
mul
,
div
)
);
}
}
/*************************/
/* more arithmetic */
/*************************/
};
/*!
template
<
typename
T
=
DEF_LENGTH_VALUE
>
class
LENGTH_UNITS
{
* Scale vector to rational number, inplace (like operator *=).
protected
:
* @param mul numerator ( length is multiplied by this value )
enum
* @param div denominator ( length is divided by this value )
* @return scaled vector
*/
LENGTH_XY
&
setByRatio
(
int
mul
,
int
div
)
{
{
m_X
.
setByRatio
(
mul
,
div
);
METRE
=
1000000000
,
/* The ONLY constant connecting length to the real world */
m_Y
.
setByRatio
(
mul
,
div
);
return
*
this
;
}
/*!
INCH
=
METRE
/
10000
*
254
* Multiplies vector length by integer number.
};
* @param y factor
public
:
* @return scaled vector
static
LENGTH
<
T
,
1
>
metre
(
void
)
{
*/
return
T
(
METRE
);
const
LENGTH_XY
operator
*
(
int
y
)
const
{
return
LENGTH_XY
(
m_X
*
y
,
m_Y
*
y
);
}
}
static
LENGTH
<
T
,
1
>
decimetre
(
void
)
{
/*!
return
T
(
METRE
/
10
);
* Multiply a vector inplace
* @param y factor
* @return scaled vector
*/
LENGTH_XY
&
operator
*=
(
int
y
)
{
m_X
*=
y
;
m_Y
*=
y
;
return
*
this
;
}
}
static
LENGTH
<
T
,
1
>
centimetre
(
void
)
{
/*!
return
T
(
METRE
/
100
);
* Multiplies vector length by floating point number.
* @param y factor
* @return scaled length
*/
const
LENGTH_XY
operator
*
(
double
y
)
const
{
return
LENGTH_XY
(
m_X
*
y
,
m_Y
*
y
);
}
}
static
LENGTH
<
T
,
1
>
millimetre
(
void
)
{
/*!
return
T
(
METRE
/
1000
);
* Multiply a vector inplace
* @param y factor
* @return scaled vector
*/
LENGTH_XY
&
operator
*=
(
double
y
)
{
m_X
*=
y
;
m_Y
*=
y
;
return
*
this
;
}
}
static
LENGTH
<
T
,
1
>
micrometre
(
void
)
{
/*!
return
T
(
METRE
/
1000000
);
* Divides vector length by integer number.
* @param y divider
* @return scaled vector
*/
const
LENGTH_XY
operator
/
(
int
y
)
const
{
return
LENGTH_XY
(
m_X
/
y
,
m_Y
/
y
);
}
}
static
LENGTH
<
T
,
1
>
foot
(
void
)
{
/* do not think this will ever need */
/*!
return
T
(
INCH
*
12
);
* Divide a vector inplace
* @param y divider
* @return scaled vector
*/
LENGTH_XY
&
operator
/=
(
int
y
)
{
m_X
/=
y
;
m_Y
/=
y
;
return
*
this
;
}
}
static
LENGTH
<
T
,
1
>
inch
(
void
)
{
/*!
return
T
(
INCH
);
* Divides vector length by floating point number.
* @param y divider
* @return scaled vector
*/
const
LENGTH_XY
operator
/
(
double
y
)
const
{
return
LENGTH_XY
(
m_X
/
y
,
m_Y
/
y
);
}
}
static
LENGTH
<
T
,
1
>
mil
(
void
)
{
/*!
return
T
(
INCH
/
1000
);
* Divide a vector inplace
* @param y divider
* @return scaled vector
*/
LENGTH_XY
&
operator
/=
(
double
y
)
{
m_X
/=
y
;
m_Y
/=
y
;
return
*
this
;
}
}
};
/*!
/* shortcut */
* Outputs wxPoint in specified scale.
template
<
typename
T
,
int
D
>
class
LENGTH_UNITS
<
LENGTH
<
T
,
D
>
>:
public
LENGTH_UNITS
<
T
>
{
* @param y scale
};
* @return wxPoint
*/
const
wxPoint
toWxPoint
(
LENGTH
y
)
const
{
return
wxPoint
(
m_X
.
idiv
(
y
),
m_Y
.
idiv
(
y
)
);
}
/*!
/* TODO: argument promotion (but is this need? explicit casts would be enough) */
* Outputs wxRealPoint in specified scale.
* @param y scale
* @return wxPoint
*/
const
wxRealPoint
toWxRealPoint
(
LENGTH
y
)
const
{
return
wxRealPoint
(
m_X
/
y
,
m_Y
/
y
);
}
/*!
* Rotates vector 90 degrees ( X axis towards Y )
* @return rotated
*/
const
LENGTH_XY
rot90
(
void
)
const
{
return
LENGTH_XY
(
m_Y
,
-
m_X
);
}
};
#endif
#endif
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment