00001
00002
00003
00004
00005
00006
00007
00008 #ifndef IMPCORE_RIGID_BODIES_H
00009 #define IMPCORE_RIGID_BODIES_H
00010
00011 #include "core_config.h"
00012 #include "internal/rigid_bodies.h"
00013
00014 #include "XYZ.h"
00015 #include "XYZR.h"
00016 #include <IMP/SingletonContainer.h>
00017 #include <IMP/SingletonModifier.h>
00018 #include <IMP/Refiner.h>
00019 #include <IMP/algebra/Vector3D.h>
00020 #include <IMP/algebra/Rotation3D.h>
00021 #include <IMP/algebra/Transformation3D.h>
00022
00023 IMPCORE_BEGIN_NAMESPACE
00024
00025
00026 class RigidMember;
00027
00028 IMP_DECORATORS(RigidMember, XYZs);
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 class IMPCOREEXPORT RigidBody: public XYZ {
00067
00068
00069
00070
00071 algebra::VectorD<3> get_coordinates(RigidMember p) const;
00072
00073 void add_member_internal(XYZ d,
00074 const algebra::Rotation3D& roti,
00075 const algebra::VectorD<3>& transi, bool cover);
00076 static RigidBody internal_setup_particle(Particle *p,
00077 const XYZs &members);
00078 IMP_CONSTRAINT_DECORATOR_DECL(RigidBody);
00079 public:
00080
00081 RigidMembers get_members() const;
00082
00083 IMP_DECORATOR(RigidBody, XYZ);
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094 static RigidBody setup_particle(Particle *p,
00095 const XYZs &members);
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108 static RigidBody setup_particle(Particle *p,
00109 const RigidMembers &members);
00110
00111 ~RigidBody();
00112
00113
00114 static bool particle_is_instance(Particle *p) {
00115 return internal::get_has_required_attributes_for_body(p);
00116 }
00117
00118
00119
00120 algebra::VectorD<3> get_coordinates() const {
00121 return XYZ::get_coordinates();
00122 }
00123
00124
00125 IMP::algebra::Transformation3D get_transformation() const;
00126
00127
00128
00129
00130
00131
00132
00133 void set_transformation(const IMP::algebra::Transformation3D &tr);
00134
00135
00136
00137
00138 void lazy_set_transformation(const IMP::algebra::Transformation3D &tr);
00139
00140 bool get_coordinates_are_optimized() const;
00141
00142
00143 void set_coordinates_are_optimized(bool tf);
00144
00145
00146 void normalize_rotation();
00147
00148
00149 void update_members();
00150
00151
00152 algebra::VectorD<4> get_rotational_derivatives() const;
00153
00154 unsigned int get_number_of_members() const;
00155
00156 RigidMember get_member(unsigned int i) const;
00157
00158
00159 void add_member(XYZ d);
00160
00161
00162
00163
00164
00165 void add_member(RigidBody o);
00166 };
00167
00168 IMP_OUTPUT_OPERATOR(RigidBody);
00169
00170 typedef IMP::Decorators<RigidBody, XYZs> RigidBodies;
00171 typedef IMP::Decorators<RigidBody, XYZsTemp> RigidBodiesTemp;
00172
00173
00174
00175
00176
00177
00178 class IMPCOREEXPORT RigidMember: public XYZ {
00179 public:
00180 IMP_DECORATOR(RigidMember, XYZ);
00181
00182 RigidBody get_rigid_body() const;
00183
00184
00185 algebra::VectorD<3> get_internal_coordinates() const {
00186 return algebra::VectorD<3>(get_particle()
00187 ->get_value(internal::rigid_body_data().child_keys_[0]),
00188 get_particle()
00189 ->get_value(internal::rigid_body_data().child_keys_[1]),
00190 get_particle()
00191 ->get_value(internal::rigid_body_data().child_keys_[2]));
00192 }
00193
00194
00195 void set_internal_coordinates(const algebra::VectorD<3> &v) const {
00196 get_particle()->set_value(internal::rigid_body_data().child_keys_[0],
00197 v[0]);
00198 get_particle()->set_value(internal::rigid_body_data().child_keys_[1],
00199 v[1]);
00200 get_particle()->set_value(internal::rigid_body_data().child_keys_[2],
00201 v[2]);
00202 }
00203
00204 void set_internal_transformation(const algebra::Transformation3D& v) {
00205 IMP_USAGE_CHECK(
00206 get_particle()->has_attribute(internal::rigid_body_data().lquaternion_[0]),
00207 "Can only set the internal transformation if member is"
00208 << " a rigid body itself.");
00209 get_particle()->set_value(internal::rigid_body_data().child_keys_[0],
00210 v.get_translation()[0]);
00211 get_particle()->set_value(internal::rigid_body_data().child_keys_[1],
00212 v.get_translation()[1]);
00213 get_particle()->set_value(internal::rigid_body_data().child_keys_[2],
00214 v.get_translation()[2]);
00215
00216 get_particle()->set_value(internal::rigid_body_data().lquaternion_[0],
00217 v.get_rotation().get_quaternion()[0]);
00218 get_particle()->set_value(internal::rigid_body_data().lquaternion_[1],
00219 v.get_rotation().get_quaternion()[1]);
00220 get_particle()->set_value(internal::rigid_body_data().lquaternion_[2],
00221 v.get_rotation().get_quaternion()[2]);
00222 get_particle()->set_value(internal::rigid_body_data().lquaternion_[3],
00223 v.get_rotation().get_quaternion()[3]);
00224 }
00225
00226 algebra::Transformation3D get_internal_transformation() const {
00227 IMP_USAGE_CHECK(
00228 get_particle()->has_attribute(internal::rigid_body_data().lquaternion_[0]),
00229 "Can only set the internal transformation if member is a "
00230 << "rigid body itself.");
00231 algebra::VectorD<3>
00232 tr(get_particle()->get_value(internal::rigid_body_data().child_keys_[0]),
00233 get_particle()->get_value(internal::rigid_body_data().child_keys_[1]),
00234 get_particle()->get_value(internal::rigid_body_data().child_keys_[2]));
00235 algebra::Rotation3D
00236 rot(get_particle()->get_value(internal::rigid_body_data()
00237 .lquaternion_[0]),
00238 get_particle()->get_value(internal::rigid_body_data()
00239 .lquaternion_[1]),
00240 get_particle()->get_value(internal::rigid_body_data()
00241 .lquaternion_[2]),
00242 get_particle()->get_value(internal::rigid_body_data()
00243 .lquaternion_[3]));
00244 return algebra::Transformation3D(rot, tr);
00245 }
00246
00247
00248
00249 void set_coordinates(const algebra::VectorD<3> ¢er) {
00250 XYZ::set_coordinates(center);
00251 }
00252
00253
00254 void set_coordinates(const algebra::Transformation3D &tr) {
00255 set_coordinates(tr.get_transformed(get_internal_coordinates()));
00256 }
00257 ~RigidMember();
00258
00259
00260 static bool particle_is_instance(Particle *p) {
00261 return internal::get_has_required_attributes_for_member(p);
00262 }
00263 };
00264
00265 IMP_OUTPUT_OPERATOR(RigidMember);
00266
00267 #ifndef IMP_DOXYGEN
00268
00269 class IMPCOREEXPORT RigidMembersRefiner: public Refiner {
00270 public:
00271 RigidMembersRefiner():Refiner("RigidMembersRefiner%d"){}
00272 IMP_SIMPLE_REFINER(RigidMembersRefiner);
00273 };
00274
00275 namespace internal {
00276 IMPCOREEXPORT RigidMembersRefiner* get_rigid_members_refiner();
00277 }
00278 #endif
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288 inline void transform(RigidBody a, const algebra::Transformation3D&tr) {
00289 a.set_transformation(algebra::compose(tr,a.get_transformation()));
00290 }
00291
00292 IMPCORE_END_NAMESPACE
00293
00294 #endif