Martin A
Martin A

Reputation: 45

Creating a SymPy Triangle three-dimensional points

I am new to SymPy and I would like to create a SymPy-Triangle from three dimensional points e.g. to obtain its surface area:

import numpy as np
import sympy as sp

p1 = np.array([1,1,1])
p2 = np.array([3,2,2])
p3 = np.array([2,3,4])

It is not possible to create a Triangle object like that:

triangle = sp.Triangle(p1,p2,p3,) #Won't work: Nonzero coordinates cannot be removed.

In a next move I created a plane on the xy-plane with z=0 and projected the original points of the triangle onto that plane:

plane = sp.Plane((0,0,0), (1,0,0), (0,1,0))

p1_proj = plane.projection(p1) # Point3D(1,1,0)
p2_proj = plane.projection(p2) # Point3D(2,2,0)
p3_proj = plane.projection(p3) # Point3D(3,3,0)

triangle_proj = sp.Triangle(p1_proj, p2_proj, p3_proj,)
area_proj = triangle_proj.area # 3/2

Now I do not get an error anymore, because all the z-components of the projected points are zero, but the triangle is now obviously also distorted and thus its area has changed:

area_original = 0.5 * np.linalg.norm( np.cross((p2-p1),(p3-p1),) ) # 2.96

Does anyone know how the transform the points of my triangle, so that all the z-coordinates become zero? Maybe even using SymPy (but that’s not necessity).

Thank you so much, spatial imagination is not one of my strengths!
Best regards Martin

Upvotes: 0

Views: 435

Answers (2)

Tim Pederick
Tim Pederick

Reputation: 500

smichr’s answer is fine if everything you need from the triangle is independent of its location: its area, angles, circumradius, etc.

But if not—say, if you need 3D coordinates for the circumcentre of a triangle not on the xy plane—the answer is that Sympy doesn’t support this directly.

At least, not yet. From the current documentation, Geometry → Future Work → Three Dimensions and Beyond:

Currently a limited subset of the geometry module has been extended to three dimensions, but it certainly would be a good addition to extend more. This would probably involve a fair amount of work since many of the algorithms used are specific to two dimensions.

To get these yourself, you can work in the xy plane and then transform coordinates to your triangle’s actual plane. Sympy probably won’t be much help here, but perhaps 3D rotations come under the “Future Work” above? (3D translations work just fine, by adding sympy.Point3D instances).

A simpler approach may be to use barycentric coordinates, which for our purposes are just a weighted average of the triangle’s vertices. Finding the barycentric coordinates of the point(s) you need may be as simple as looking them up (they’re well known for typical points related to triangles, like its centres), but I’ll leave finding the barycentric coordinates of an arbitrary point as an exercise for the reader!

Then, convert them to 3D Cartesian coordinates like so:

>>> v = ... # Vertices as sympy.Point3D instances
>>> b = ... # Barycentric coordinates
>>> p = sum(map(math.prod, zip(v, b)),
            start=Point(0, 0, 0)) / sum(b)

(If working with normalised barycentric coordinates, where sum(b) == 1, the division can be skipped.)

Upvotes: 1

smichr
smichr

Reputation: 19029

Triangle can be constructed by indicating the length of each side of the triangle so instead of looking for a transform you can just calculate the length of each side as defined in the Plane:

>>> a,b,c=map(Point,([1,1,1],[3,2,2],[2,3,4]))
>>> Triangle(sss=(a.distance(b),b.distance(c),c.distance(a)))
Triangle(Point2D(0, 0), Point2D(sqrt(6), 0), Point2D(7*sqrt(6)/6, sqrt(210)/6))
>>> _.area
sqrt(35)/2
>>> _.n()
2.95803989154981

The transformation of a plane to the xy plane is discussed here.

Upvotes: 1

Related Questions