help with the geometric module project api

60 views
Skip to first unread message

Stefan Krastanov

unread,
May 23, 2014, 1:44:58 PM5/23/14
to sy...@googlegroups.com
Hi all,

It would be great if you can comment on the upcoming API for the 3D
geometry module.

The current module has a nice class structure for 2D objects (points,
planar figures, conics) and does not support anything in 3D.

For the moment this is the approach taken to extending it to 3D. It
nicely minimizes code duplication, but something does not seem right
to me.

- class Point3D
- it receives 2 or 3 coordinates on creation
- 2 points means that the last one is set to zero by default
- it has all the fancy methods to find midpoints, create lines, etc.

- class Point (it is Point2D, but for backward compatibility is called
just Point)
- subclass of Point3D
- it is a very shallow subclass of Point3D where the last coordinate
is set to 0
- it has a method to convert to a 3D point and most of the
calculations are done with it


pros:
- very little code duplication
cons:
- a lot of `if isinstance` inside the Point3D code to check and
convert Point to Point3D
- Point and Point3D seem unnecessarily tightly coupled
- I do not like how a lot of the classification whether something is
3d or 2d is done by checking the number of coordinates (implicitly)
and not by classes (explicitly)


I think a better approach would be to not touch `Point` at all, and
implement Point3D independently. This will require some minor code
duplication. However total length of code will not be higher and the
code will be much easier to understand. Compare this to right now:
there are a lot of `isinstance` checks in the base implementation of
most methods, which is a serious antipattern.

When this is done we can see whether it makes sense to abstract
anything in a base class.

Akshay

unread,
May 23, 2014, 1:59:10 PM5/23/14
to sy...@googlegroups.com, stefan.k...@yale.edu
Here is the link to the code https://github.com/akshayah3/sympy/blob/master/sympy/geometry/point.py

The reason for the classes to be tightly coupled was to enable such computations
 a = Point3D(1,2,3)
 a.distance(Point(2,3)) This returns the distance between these two points.
This is one of the possible four combinations(as in distance between 2 3D points, 2 2D points, 3D and 2D point)

So i have a question
1) Should the above code work as in should it give the result (sqrt(11)) in the above case or should it raise an nonimplement error as they are 2 different classes(3D and 2D)
And this is the case in all other methods aswell like midpoint this also has 4 combinations
Point3D(1,2,3).midpoint(Point(1,2)), Point3D(1,2,3).midpoint(Point3D(1,2,4)) and similarly 2 2D cases.

Akshay

unread,
May 23, 2014, 2:01:40 PM5/23/14
to sy...@googlegroups.com, stefan.k...@yale.edu

Joachim Durchholz

unread,
May 23, 2014, 3:08:55 PM5/23/14
to sy...@googlegroups.com
What's the status of those things that exist in the same way regardless
of number of dimensions?
Things like calculating a volume, constructing an orthogonal base,
calculating distances - all the linear algebra stuff that applies to
geometry.

Ideally, it would all be the same code base (or transformation rule set).

I know nothing about the geometric module project or its goals, so I'm
not sure whether this kind of thing is even useful for the project, let
alone doable.
But I'd like to know. The question which of the various geometric ADTs
and algorithms transfer neatly to higher dimensions, which do not, and
which are mere analogies has been haunting me since high school, so I'm
too curious to not ask ;-)

Stefan Krastanov

unread,
May 23, 2014, 5:14:05 PM5/23/14
to sy...@googlegroups.com
@Joachim, you are right about what you say, but I do not think it
applies to the geometry module.

Everything below is just an opinion, moreover I am not the original
author the the geometry module, so take it with a grain of salt.

The geometry module was created as a tool for high school euclidean 2d
geometry and it was never meant to be used in advanced abstract math
or to work in any number of dimensions (e.g. nobody will use it for
elliptical curves cryptography or for geometry over a field that is
not the real numbers). We have two options to go forward:

- generalize it to N dimensions (which is not what this gsoc project
is doing and it will probably never be done (a completely new module
is more realistic))
- make it work in 3D (what this project is doing and what I discuss below)

Given that it is only 2d and 3d that we are working on, I think a
minor amount of code duplication[1] is a good thing, as it will make
the code simpler.

[1] at least in the beginning: during code reviews we can see whether
there is something worth abstracting away.

Going back to the current work in progress:
While I do not have a very strong opinion on the above, there is one
thing I insist on. A large amount of `if 2d:... elif 3d:...` snippets
is an obvious antipattern in an OO language. The current works has a
lot of them and it was the reason for which we decided to push the
conversation to the mailing list.
> --
> You received this message because you are subscribed to the Google Groups
> "sympy" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to sympy+un...@googlegroups.com.
> To post to this group, send email to sy...@googlegroups.com.
> Visit this group at http://groups.google.com/group/sympy.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/sympy/537F9CC3.5060501%40durchholz.org.
>
> For more options, visit https://groups.google.com/d/optout.

Stefan Krastanov

unread,
May 23, 2014, 5:19:40 PM5/23/14
to sy...@googlegroups.com
> The reason for the classes to be tightly coupled was to enable such
> computations
> a = Point3D(1,2,3)
> a.distance(Point(2,3)) This returns the distance between these two points.
> This is one of the possible four combinations(as in distance between 2 3D
> points, 2 2D points, 3D and 2D point)
>
> So i have a question
> 1) Should the above code work as in should it give the result (sqrt(11)) in
> the above case or should it raise an nonimplement error as they are 2
> different classes(3D and 2D)

My opinion was that it does not make sense to calculate anything
between 3D and 2D points, as they live in different spaces. However
there should be a way to promote 2D point to 3D like the following:

>>> plane = ... # some object representing a 2D plane in 3D space
>>> point = ... # some 2d point
>>> point3D = promote_to_3D(point, plane)
# taking `point`, assuming that it is on `plane` and
# returning the corresponding 3D point

There can be a default plane (x,y,z=0)

There should also be a way to project a 3d point on a plane or a line.

Joachim Durchholz

unread,
May 23, 2014, 6:38:26 PM5/23/14
to sy...@googlegroups.com
Am 23.05.2014 23:13, schrieb Stefan Krastanov:
> @Joachim, you are right about what you say, but I do not think it
> applies to the geometry module.
>
> [...]
>
> - generalize it to N dimensions (which is not what this gsoc project
> is doing and it will probably never be done (a completely new module
> is more realistic))
> - make it work in 3D (what this project is doing and what I discuss below)

As I half-suspected, what I'm after isn't in the goals, so it's
irrelevant for the project.
Ignore my feedback for the geometry module then :-)

I also agree that a fully general module would likely make it harder to
work with in education, so even restricted 2d and 3d modules do have a
solid purpose.
It *might* be a good idea to rewrite these modules so that they call a
generalized arbitrary-dimension geometry module, but since such a module
does not exist, that's not currently viable and something to refactor in
a future project.

> Given that it is only 2d and 3d that we are working on, I think a
> minor amount of code duplication[1] is a good thing, as it will make
> the code simpler.
>
> [1] at least in the beginning: during code reviews we can see whether
> there is something worth abstracting away.

+1

> Going back to the current work in progress:
> While I do not have a very strong opinion on the above, there is one
> thing I insist on. A large amount of `if 2d:... elif 3d:...` snippets
> is an obvious antipattern in an OO language. The current works has a
> lot of them and it was the reason for which we decided to push the
> conversation to the mailing list.

+1
For each such if-elif clause, there should be a function, overridden
with the code from "if 2d:" in the 2d module and with the code from "if
3d:" from the 3d module.
That's a fairly mechanical transformation. The real fun begins when you
try to give these functions meaningful names - however, that's a great
way to discover which concepts apply across dimensions and which don't.

Alan Bromborsky

unread,
May 23, 2014, 7:11:10 PM5/23/14
to sy...@googlegroups.com
What are you looking for in a geometry module. Please give an example
of a problem you wish to pose.

Stefan Krastanov

unread,
May 23, 2014, 7:34:38 PM5/23/14
to sy...@googlegroups.com
> What are you looking for in a geometry module. Please give an example of a
> problem you wish to pose.

At the moment it is best adapted at simple euclidean geometry question
(high school geometry and stereometry + simple operations on conics):

Give me the intersection of this and that. Define this conic, rotate
it that much, give me the intersection with this circle, etc. Test
whether this point is in this triangle, test whether this line and
this figure intersect.

Alan Bromborsky

unread,
May 23, 2014, 8:21:41 PM5/23/14
to sy...@googlegroups.com

Akshay Narasimha

unread,
May 23, 2014, 10:53:31 PM5/23/14
to sy...@googlegroups.com
My opinion was that it does not make sense to calculate anything
between 3D and 2D points, as they live in different spaces. However
there should be a way to promote 2D point to 3D like the following:

>>> plane = ... # some object representing a 2D plane in 3D space
>>> point = ... # some 2d point
>>> point3D = promote_to_3D(point, plane)
# taking `point`, assuming that it is on `plane` and
# returning the corresponding 3D point

There can be a default plane (x,y,z=0)

There should also be a way to project a 3d point on a plane or a line.



We could do it in the Plane class as you above described but that would also require a lot of if instance statements in the plane class as well  as we have to check whether a point is 2D or 3D and act accordingly.

So according to me there is no way of compromising these if else statements as they will come in one class or the other.




--
You received this message because you are subscribed to a topic in the Google Groups "sympy" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/sympy/hqHC-9cA9UM/unsubscribe.
To unsubscribe from this group and all its topics, send an email to sympy+un...@googlegroups.com.

To post to this group, send email to sy...@googlegroups.com.
Visit this group at http://groups.google.com/group/sympy.

Stefan Krastanov

unread,
May 24, 2014, 2:46:25 AM5/24/14
to sy...@googlegroups.com
> We could do it in the Plane class as you above described but that would also
> require a lot of if instance statements in the plane class as well as we
> have to check whether a point is 2D or 3D and act accordingly.

I do not see why this would be the case. Could you give an example?
Projections work only on 3d points. Promotion to 3d works only on 2d
points. These are very different operations. There is no need of
switch/case statements.

Akshay Narasimha

unread,
May 24, 2014, 9:39:02 AM5/24/14
to sy...@googlegroups.com
I think there is a bit of misunderstanding, are u saying  that after converting a 2D point to 3D using a plane we can then find the distance between this converted point and another 3D point ,otherwise what is the use of using a plane? and which plane do you intend to use in the above transformation ?
 


--
You received this message because you are subscribed to a topic in the Google Groups "sympy" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/sympy/hqHC-9cA9UM/unsubscribe.
To unsubscribe from this group and all its topics, send an email to sympy+un...@googlegroups.com.
To post to this group, send email to sy...@googlegroups.com.
Visit this group at http://groups.google.com/group/sympy.

Stefan Krastanov

unread,
May 24, 2014, 12:25:35 PM5/24/14
to sy...@googlegroups.com
After converting a 2D point to a 3D point (through whatever method -
the example with the plane was just one of many), we have a 3D point.
We can do with it all the normal operations that can be done with a 3D
point.

The user is free to define any plane.
> You received this message because you are subscribed to the Google Groups
> "sympy" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to sympy+un...@googlegroups.com.
> To post to this group, send email to sy...@googlegroups.com.
> Visit this group at http://groups.google.com/group/sympy.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/sympy/CAC_H1WEnuvyE9EWpjL0fiF2vWErT-D4M9ytKt6DDWPqk-SKm7w%40mail.gmail.com.
Reply all
Reply to author
Forward
0 new messages