# SpaceFuncsDoc

### From OpenOpt

**SpaceFuncs Documentation**

Made by Dmitrey |

## Contents |

# Geometry objects

The following geometry objects are implemented for now in SpaceFuncs module:

**Point, Line, LineSegment, Circle, Plane, Triangle, Polygon, Sphere, Polytope, Polyhedron, Tetrahedron**. Some more are intended to be done in next SpaceFuncs release.

## Point

Examples of valid constructor calls

A = Point(1, 5) # 2D point with coordinates 1 and 5 A = Point(0, 5, 6, 7.5) # 4D point with coordinates 0, 5, 6, 7.5

Examples of parametrized construction (reading FuncDesigner documentation before is recommended):

from FuncDesigner import * from SpaceFuncs import * spaceDimension = 2 a,b,c = oovars(3, size=spaceDimension) p1, p2, p3 = Point(a), Point(b), Point(c)

Also you can parametrize SpaceFuncs objects by general oofun (a FuncDesigner function over oovars, maybe connected from C/Fortran/other languages).

Alternatively, you can parametrize only some coordinates of points, e.g.

p0 = Point(a, b, c) p1, p2, p3 = Point(1,2,a), Point(2,b,4), Point(c, 2*a+exp(b), 7.5)

To resolve point coordinates into real numbers (as well as for other SpaceFuncs geometry objects), you should evaluate it on a Python dictionary of pairs (parameter, value), e.g. for former example p1({a:[5,3]}) will be Point(5,3) and for latter example p1({a:5,b:3,c:0}) will be Point(1,2,5). The dictionary should have all oovars values used for parametrization of the point.

Point constructor assigns a name like "unnamed14". To rename a point (e.g. for graphic output) you should evaluate it on a string parameter, e.g.

A = Point(1, 5) ... Plot(..., A('A'), ...) # or P = Point(1, 5)('A')

Point is derived class from recently created FuncDesigner ooarray, and latter is derived class from NumPy ndarray. Thus basic arithmetic operations, such as -a, a+b, a-b, a*scalar, a/scalar create another Point class instances. For example, to get a middle of line segment between A abd B points, you can use M = 0.5*(A+B) or (A+B)/2. Some other operations like sin(point) also return Point instance, but you should use it carefully.

Methods:

method |
arguments |
usage example |

distance | point or line or Plane | d = p1.distance(p2) |

projection | line or plane | p2 = p1.projection(myLine) |

(since v. 0.38) symmetry (*) |
point or line or plane | p2 = p1.symmetry(p) |

(since v. 0.38) rotate (**) |
RotationCenter, angle | newPoint = originPoint.rotate(P, 3.14), P2 = P1.rotate([1,2], 0.4) |

perpendicular (line to object passing through the given point from or beyond the object) |
line or plane | line2 = p.perpendicular(line1) |

(*) Thus, for example, you can build symmetric triangle via T2 = Triangle([p.symmetry(obj) for p in T.vertices]). If you use the operation very often, method **symmetry** could be extended (on demand) in SpaceFuncs code for some other required objects.

(**) Angle units are radians; currently the method is implemented for 2-dimensional space only; for other spaces you can use FuncDesigner.dot(RotationMatrix ,Point - BasePoint) + BasePoint (implementing it with more convenient API is in FuturePlans); if BasePoint is (0,0), you can just use prevPoint.rotate(0, angle)

More examples:

## Line

Examples of valid constructor calls

A = Point(1, 5) B = Point(5, 6) l = Line(A, B) # or mere l = Line((1,5), (5,6))

Examples of parametrized construction (reading FuncDesigner documentation before is recommended):

from FuncDesigner import * from SpaceFuncs import * spaceDimension = 4 a,b = oovars(2, size=spaceDimension) p1, p2 = Point(a), Point(b) l = Line(p1, p2)

Alternatively, you can construct Line using a point it is passed through and its direction, e.g.

l = Line((1,2,3), direction = (5,6,7))

Methods:

method |
argument |
usage example |

projection | plane | l2 = l1.projection(plane1) |

& (intersection) | line | P = l1 & l2; is calculated in general N-dimensional space as 0.5*(P1 + P2), where P1 and P2 minimize distance between l1 and l2 |

skewLinesNearestPoints (SF function) |
two lines | P1, P2 = skewLinesNearestPoints(line1, line2) |

More examples:

## LineSegment

Constructor: ls = LineSegment(point1, point2)

Methods:

method |
argument |
usage example |

length | r = ls.length | |

(since v. 0.38) middle | M = ls.middle |

## Circle

Constructor: circle = Circle(center, radius)

(will be available as circle.center and circle.radius)

Methods:

method |
argument |
usage example |

S, area | area = circle.S, area = circle.area |

## Sphere

Constructor: sphere = Sphere(center, radius)

(will be available as sphere.center and sphere.radius)

Methods:

method |
argument |
usage example |

S, area | area = sphere.S, area = sphere.area | |

V, volume | volume = sphere.V, volume = sphere.volume (currently works for 3D space only) |

## Polytope

Constructor: P = Polytope(point1, point2, ..., point_n)

or

P = Polytope(Python_list_of_points)

**P.vertices** will be Python list of the polytope vertices.

Methods:

method |
argument |
usage example |

centroid | Centroid = P.centroid |

## Polygon

Derived class from Polytope.

Constructor: P = Polygon(point1, point2, ..., point_n)

or

P = Polygon(Python_list_of_points)

Methods:

method |
argument |
usage example |

centroid (derived from Polytope) |
Centroid = P.centroid | |

sides | sides = P.sides | |

P, perimeter | Perimeter = P.P, Perimeter = P.perimeter | |

angles | angles = P.angles | |

S, area | area = P.S, area = P.area |

More examples:

## Triangle

Derived class from Polygon.

Constructor: P = Triangle(point1, point2, point3)

or

P = Triangle([point1,point2,point3])

Methods (in addition to Polygon methods):

method |
argument |
usage example |

R, circumCircleRadius |
InscribedCircle = T.InscribedCircle, incenter = T.I (also available as T.InscribedCircle.center) |

Triangle centroid (derived from Polygon) is also available as M.

More examples:

## Polygedron

Currently just a parent class for Tetrahedron

## Tetrahedron

Derived class from Polygedron.

Constructor: T = Tetrahedron(point1, point2, point3, point4)

or

T = Tetrahedron([point1,point2,point3,point4])

Methods:

method |
argument |
usage example |

S, square |
incenter = T.incenter, incenter = T.I |

More examples:

# Solving systems of geometric equations

This is intended to be improved till next SpaceFuncs release.

from SpaceFuncs import Triangle, Plot from FuncDesigner import * from openopt import NLP, NLSP # let's create parameterized triangle : a,b,c = oovars(3) T = Triangle((1,2,a),(2,b,4),(c,6.5,7)) # let's create an initial estimation to the problems below startValues = {a:1, b:0.5, c:0.1} # you could mere set any, but sometimes a good estimation matters # let's find an a,b,c values wrt r = 1.5 with required tolerance 10^-5, R = 4.2 and tol 10^-4, a+c == 2.5 wrt tol 10^-7 # if no tol is provided, p.contol is used (default 10^-6) equations = [(T.r == 1.5)(tol=1e-5) , (T.R == 4.2)(tol=1e-4), (a+c == 2.5)(tol=1e-7)] prob = NLSP(equations, startValues) result = prob.solve('nssolve', iprint = -1) # nssolve is name of the solver involved print('\nsolution has%s been found' % ('' if result.stopcase > 0 else ' not')) print('values:' + str(result(a, b, c))) # [1.5773327492140974, -1.2582702179532217, 0.92266725078590239] print('triangle sides: '+str(T.sides(result))) # [8.387574299361475, 7.0470774415247455, 4.1815836020856336] print('orthocenter of the triangle: ' + str(T.H(result))) # [ 0.90789867 2.15008869 1.15609611]

# Numerical optimization

This is intended to be improved till next SpaceFuncs release.

from FuncDesigner import * from openopt import NLP, NLSP # let's create parameterized triangle : a,b,c = oovars(3) T = Triangle((1,2,a),(2,b,4),(c,6.5,7)) # let's create an initial estimation to the problems below startValues = {a:1, b:0.5, c:0.1} # you could mere set any, but sometimes a good estimation matters # let's find minimum inscribed radius subjected to the constraints a<1.5, a>-1, b<0, a+2*c<4, log(1-b)<2] : objective = T.r prob = NLP(objective, startValues, constraints = [a<1.5, a>-1, b<0, a+2*c<4, log(1-b)<2]) result1 = prob.minimize('ralg', iprint = -1) # ralg is name of the solver involved, see http://openopt.org/ralg for details print('\nminimal inscribed radius: %0.3f' % T.r(result1)) # 1.321 print('optimal values:' + str(result1(a, b, c))) # [1.4999968332804028, 2.7938728907900973e-07, 0.62272481283890913] #let's find minimum outscribed radius subjected to the constraints a<1.5, a>-1, b<0, a+2*c<4, log(1-b)<2] : prob = NLP(T.R, startValues, constraints = (a<1.5, a>-1, b<0, (a+2*c<4)(tol=1e-7), log(1-b)<2)) result2 = prob.minimize('ralg', iprint = -1) print('\nminimal outscribed radius: %0.3f' % T.R(result2)) # 3.681 print('optimal values:' + str(result2(a, b, c))) # [1.499999901863762, -1.7546960034401648e-06, 1.2499958739399943]

# Graphic output

Python language has lots of graphic libraries, and you can involve any of them for SpaceFuncs results visualization. For 2D plotting we definitely recommend matplotlib, that is de-facto standard for scientific Python programming (its syntax is similar to MATLAB plot tool).

For to simplify some basic operations, we have provided some basic graphic output features in SpaceFuncs code. They are available via using function *Plot(sequence of SpaceFuncs objects)*. Currently name of a point to be plotted is shown if and only if it is user-provided (automatically point receive names as "unnamed"+some_number, e.g. *unnamed123*). Like it is done for FuncDesigner oofuns, you can change point name via mere evaluation the point on a string argument in any place of code, e.g. sphereCenter = point(1,2,3)('O').

Here's an example and its output:

from SpaceFuncs import * A, B, C = Point(0, 8)('A'), Point(3, 7)('B'), Point(3.5, 5)('C') T = Triangle(A, B, C) Plot(T, T.InscribedCircle, T.CircumCircle, LineSegment(B, T.incenter('I')), LineSegment(C, T.incenter), # you can use both T.incenter and T.InscribedCircle.center, LineSegment(A, T.InscribedCircle.center), # T.circumCircleCenter and T.CircumCircle.center LineSegment(T.circumCircleCenter('O'), T.incenter), )

# Future Plans

See FuturePlans