// $Id$ // // Copyright (C) 2005 Rational Discovery LLC // // @@ All Rights Reserved @@ // This file is part of the RDKit. // The contents are covered by the terms of the BSD license // which is included in the file license.txt, found at the root // of the RDKit source tree. // #include #include #include namespace python = boost::python; namespace{ struct Point3D_pickle_suite : python::pickle_suite { static python::tuple getinitargs(RDGeom::Point3D const &pt){ return python::make_tuple(pt.x,pt.y,pt.z); } }; struct Point2D_pickle_suite : python::pickle_suite { static python::tuple getinitargs(RDGeom::Point2D const &pt){ return python::make_tuple(pt.x,pt.y); } }; struct PointND_pickle_suite : python::pickle_suite { static python::tuple getinitargs(RDGeom::PointND const &pt){ return python::make_tuple(pt.dimension()); } static python::tuple getstate(RDGeom::PointND const &pt){ python::list res; for(unsigned int i=0;i(state.attr("__len__")()); for(unsigned int i=0;i(state[i]); } } }; } namespace RDGeom { std::string Point3Ddoc = "A class to represent a three-dimensional point\n\ The x, y, and z coordinates can be read and written using either attributes\n\ (i.e. pt.x = 4) or indexing (i.e. pt[0] = 4).\n"; std::string Point2Ddoc = "A class to represent a two-dimensional point"; std::string PointNDdoc = "A class to represent an N-dimensional point"; double point3Ddist(const Point3D &pt1, const Point3D &pt2) { Point3D tpt(pt1); tpt -= pt2; return tpt.length(); } double pointNdGetItem(const PointND &self,int idx){ if(idx>=static_cast(self.dimension()) || idx<-1*static_cast(self.dimension())) throw IndexErrorException(idx); if(idx<0) idx=self.dimension()+idx; return self[idx]; } double pointNdSetItem(PointND &self,int idx,double val){ if(idx>=static_cast(self.dimension()) || idx<-1*static_cast(self.dimension())) throw IndexErrorException(idx); if(idx<0) idx=self.dimension()+idx; self[idx]=val; return val; } double point3dGetItem(const Point3D &self,int idx){ switch(idx){ case 0: case -3: return self.x; break; case 1: case -2: return self.y; break; case 2: case -1: return self.z; break; default: throw IndexErrorException(idx); } } double point2dGetItem(const Point2D &self,int idx){ switch(idx){ case 0: case -2: return self.x; break; case 1: case -1: return self.y; break; default: throw IndexErrorException(idx); } } struct Point_wrapper { static void wrap() { python::class_("Point3D", Point3Ddoc.c_str(), python::init<>("Default Constructor")) .def(python::init()) .def_readwrite("x", &Point3D::x) .def_readwrite("y", &Point3D::y) .def_readwrite("z", &Point3D::z) .def("__getitem__", point3dGetItem) .def("__len__",&Point3D::dimension) .def("__iadd__", &Point3D::operator+=, python::return_value_policy(), "Addition to another point") .def("__isub__", &Point3D::operator-=, python::return_value_policy(), "Vector difference") .def(python::self - python::self) .def(python::self -= python::self) .def(python::self + python::self) .def(python::self += python::self) .def(python::self * double()) .def(python::self / double()) .def("__imul__", &Point3D::operator*=, python::return_value_policy(), "Scalar multiplication") .def("__idiv__", &Point3D::operator/=, python::return_value_policy(), "Scalar division") .def("Normalize", &Point3D::normalize, "Normalize the vector (using L2 norm)") .def("Length", &Point3D::length, "Length of the vector") .def("Distance", point3Ddist, "Distance from this point to another point") .def("LengthSq", &Point3D::lengthSq, "Square of the length") .def("DotProduct", &Point3D::dotProduct, "Dot product with another point") .def("AngleTo", &Point3D::angleTo, "determines the angle between a vector to this point (between 0 and PI)") .def("SignedAngleTo", &Point3D::signedAngleTo, "determines the signed angle between a vector to this point (between 0 and 2*PI)") .def("DirectionVector", &Point3D::directionVector, "return a normalized direction vector from this point to another") .def("CrossProduct", &Point3D::crossProduct, "Get the cross product between two points") .def_pickle(Point3D_pickle_suite()) ; python::class_("Point2D", Point2Ddoc.c_str(), python::init<>("Default Constructor")) .def(python::init()) .def_readwrite("x", &Point2D::x) .def_readwrite("y", &Point2D::y) .def("__getitem__", point2dGetItem) .def("__len__",&Point2D::dimension) .def(python::self - python::self) .def(python::self -= python::self) .def(python::self + python::self) .def(python::self += python::self) .def(python::self * double()) .def(python::self / double()) .def("__imul__", &Point2D::operator*=, python::return_value_policy(), "Scalar multiplication") .def("__idiv__", &Point2D::operator/=, python::return_value_policy(), "Scalar division") .def("Normalize", &Point2D::normalize, "Normalize the vector (using L2 norm)") .def("Length", &Point2D::length, "Length of the vector") .def("LengthSq", &Point2D::lengthSq, "Square of the length") .def("DotProduct", &Point2D::dotProduct, "Dot product with another point") .def("AngleTo", &Point2D::angleTo, "determines the angle between a vector to this point (between 0 and PI)") .def("SignedAngleTo", &Point2D::signedAngleTo, "determines the signed angle between a vector to this point (between 0 and 2*PI)") .def("DirectionVector", &Point2D::directionVector, "return a normalized direction vector from this point to another") .def_pickle(Point2D_pickle_suite()) ; python::class_("PointND", PointNDdoc.c_str(), python::init()) .def("__getitem__", pointNdGetItem) .def("__setitem__", pointNdSetItem) .def("__len__",&PointND::dimension) .def("__iadd__", &PointND::operator+=, python::return_value_policy(), "Addition to another point") .def("__isub__", &PointND::operator-=, python::return_value_policy(), "Vector difference") .def(python::self - python::self) .def(python::self -= python::self) .def(python::self + python::self) .def(python::self += python::self) .def(python::self * double()) .def(python::self / double()) .def("__imul__", &PointND::operator*=, python::return_value_policy(), "Scalar multiplication") .def("__idiv__", &PointND::operator/=, python::return_value_policy(), "Scalar division") .def("Normalize", &PointND::normalize, "Normalize the vector (using L2 norm)") .def("Length", &PointND::length, "Length of the vector") .def("Distance", point3Ddist, "Distance from this point to another point") .def("LengthSq", &PointND::lengthSq, "Square of the length") .def("DotProduct", &PointND::dotProduct, "Dot product with another point") .def("AngleTo", &PointND::angleTo, "determines the angle between a vector to this point (between 0 and PI)") .def("DirectionVector", &PointND::directionVector, "return a normalized direction vector from this point to another") //.def("SignedAngleTo", &PointND::signedAngleTo, // "determines the signed angle between a vector to this point (between 0 and 2*PI)") //.def("CrossProduct", &PointND::crossProduct, // "Get the cross product between two points") .def_pickle(PointND_pickle_suite()) ; python::def("ComputeDihedralAngle",computeDihedralAngle,"calculates the dihedral angle determined by four Point3D objects"); python::def("ComputeSignedDihedralAngle",computeSignedDihedralAngle,"calculates the signed dihedral angle determined by four Point3D objects"); } }; } void wrap_point() { RDGeom::Point_wrapper::wrap(); }