8 #include "quaternion.h"
10 void hkl_svector_fprintf(FILE * file
, struct hkl_svector
const * v
)
12 fprintf(file
, "|%f, %f, %f|", v
->data
[0], v
->data
[1], v
->data
[2]);
16 void hkl_svector_set(struct hkl_svector
* v
, double const x
, double const y
, double const z
)
23 int hkl_svector_cmp(struct hkl_svector
const * v
, struct hkl_svector
const * v1
)
28 if ( fabs(v
->data
[i
] - v1
->data
[i
]) > HKL_EPSILON
)
34 extern int hkl_svector_is_opposite(struct hkl_svector
const * v
, struct hkl_svector
const * v1
)
39 if ( fabs(v
->data
[i
] + v1
->data
[i
]) > HKL_EPSILON
)
44 void hkl_svector_minus_svector(struct hkl_svector
* v
, struct hkl_svector
const * v1
)
48 v
->data
[i
] -= v1
->data
[i
];
51 void hkl_svector_div_double(struct hkl_svector
* v
, double const d
)
58 void hkl_svector_times_double(struct hkl_svector
* v
, double const d
)
65 void hkl_svector_times_svector(struct hkl_svector
* v
, struct hkl_svector
const * v1
)
69 v
->data
[i
] *= v1
->data
[i
];
72 void hkl_svector_times_smatrix(struct hkl_svector
* v
, struct hkl_smatrix
const * m
)
74 struct hkl_svector tmp
;
77 v
->data
[0] = tmp
.data
[0] * m
->data
[0][0] + tmp
.data
[1] * m
->data
[1][0] + tmp
.data
[2] * m
->data
[2][0];
78 v
->data
[1] = tmp
.data
[0] * m
->data
[0][1] + tmp
.data
[1] * m
->data
[1][1] + tmp
.data
[2] * m
->data
[2][1];
79 v
->data
[2] = tmp
.data
[0] * m
->data
[0][2] + tmp
.data
[1] * m
->data
[1][2] + tmp
.data
[2] * m
->data
[2][2];
82 double hkl_svector_sum(struct hkl_svector
const * v
)
84 return v
->data
[0] + v
->data
[1] + v
->data
[2];
87 double hkl_svector_scalar_product(struct hkl_svector
const * v
, struct hkl_svector
const * v1
)
93 scalar
+= v
->data
[i
] * v1
->data
[i
];
97 void hkl_svector_vectorial_product(struct hkl_svector
* v
, struct hkl_svector
const * v1
)
99 struct hkl_svector tmp
;
102 v
->data
[0] = tmp
.data
[1] * v1
->data
[2] - tmp
.data
[2] * v1
->data
[1];
103 v
->data
[1] = tmp
.data
[2] * v1
->data
[0] - tmp
.data
[0] * v1
->data
[2];
104 v
->data
[2] = tmp
.data
[0] * v1
->data
[1] - tmp
.data
[1] * v1
->data
[0];
108 double hkl_svector_angle(struct hkl_svector
const * v
, struct hkl_svector
const * v1
)
116 norm_v
= hkl_svector_norm2(v
);
117 norm_v1
= hkl_svector_norm2(v1
);
119 // check the validity of the parameters
120 assert(norm_v
> HKL_EPSILON
);
121 assert(norm_v1
> HKL_EPSILON
);
123 norm
= norm_v
* norm_v1
;
125 cos_angle
= hkl_svector_scalar_product(v
, v1
) / norm
;
127 // problem with round
131 if (cos_angle
<= -1 )
134 angle
= acos(cos_angle
);
138 double hkl_svector_norm2(struct hkl_svector
const * v
)
140 return sqrt(v
->data
[0] * v
->data
[0] + v
->data
[1] * v
->data
[1] + v
->data
[2] * v
->data
[2]);
144 * @brief normalize a hkl_svector
145 * @return true if the hkl_svector can be normalized, false otherwise
146 * @todo check the status
148 int hkl_svector_normalize(struct hkl_svector
* v
)
150 int status
= HKL_FAIL
;
152 double norm
= hkl_svector_norm2(v
);
153 if ( norm
> HKL_EPSILON
)
155 hkl_svector_div_double(v
, norm
);
156 status
= HKL_SUCCESS
;
162 int hkl_svector_is_colinear(struct hkl_svector
const * v
, struct hkl_svector
const * v1
)
165 struct hkl_svector tmp
= *v
;
167 hkl_svector_vectorial_product(&tmp
, v1
);
168 if (hkl_svector_norm2(&tmp
) < HKL_EPSILON
)
175 void hkl_svector_randomize(struct hkl_svector
* v
)
177 v
->data
[0] = -1 + 2 * rand()/(RAND_MAX
+1.0);
178 v
->data
[1] = -1 + 2 * rand()/(RAND_MAX
+1.0);
179 v
->data
[2] = -1 + 2 * rand()/(RAND_MAX
+1.0);
182 void hkl_svector_randomize_svector(struct hkl_svector
* v
, struct hkl_svector
const * v1
)
185 hkl_svector_randomize(v
);
186 while (hkl_svector_cmp(v
, v1
) == HKL_TRUE
);
189 void hkl_svector_randomize_svector_svector(struct hkl_svector
* v
, struct hkl_svector
const * v1
, struct hkl_svector
const * v2
)
192 hkl_svector_randomize(v
);
193 while (hkl_svector_cmp(v
, v1
) == HKL_TRUE
|| hkl_svector_cmp(v
, v2
) == HKL_TRUE
);
196 /** rotate a svector around another svector with an angle */
197 void hkl_svector_rotated_around_vector(struct hkl_svector
* v
, struct hkl_svector
const * axe
, double angle
)
199 double c
= cos(angle
);
200 double s
= sin(angle
);
201 struct hkl_svector axe_n
;
202 struct hkl_svector tmp
;
205 hkl_svector_normalize(&axe_n
);
209 v
->data
[0] = (c
+ (1 - c
) * axe_n
.data
[0] * axe_n
.data
[0]) * tmp
.data
[0];
210 v
->data
[0] += ((1 - c
) * axe_n
.data
[0] * axe_n
.data
[1] - axe_n
.data
[2] * s
) * tmp
.data
[1];
211 v
->data
[0] += ((1 - c
) * axe_n
.data
[0] * axe_n
.data
[2] + axe_n
.data
[1] * s
) * tmp
.data
[2];
213 v
->data
[1] = ((1 - c
) * axe_n
.data
[0] * axe_n
.data
[1] + axe_n
.data
[2] * s
) * tmp
.data
[0];
214 v
->data
[1] += (c
+ (1 - c
) * axe_n
.data
[1] * axe_n
.data
[1]) * tmp
.data
[1];
215 v
->data
[1] += ((1 - c
) * axe_n
.data
[1] * axe_n
.data
[2] - axe_n
.data
[0] * s
) * tmp
.data
[2];
217 v
->data
[2] = ((1 - c
) * axe_n
.data
[0] * axe_n
.data
[2] - axe_n
.data
[1] * s
) * tmp
.data
[0];
218 v
->data
[2] += ((1 - c
) * axe_n
.data
[1] * axe_n
.data
[2] + axe_n
.data
[0] * s
) * tmp
.data
[1];
219 v
->data
[2] += (c
+ (1 - c
) * axe_n
.data
[2] * axe_n
.data
[2]) * tmp
.data
[2];
223 * apply a quaternion rotation to a svector
226 void hkl_svector_rotated_quaternion(struct hkl_svector
* v
, struct hkl_quaternion
const * qr
)
228 struct hkl_quaternion q
;
229 struct hkl_quaternion tmp
;
231 // compute qr * qv * *qr
233 hkl_quaternion_from_svector(&tmp
, v
);
235 hkl_quaternion_times_quaternion(&q
, &tmp
);
237 hkl_quaternion_conjugate(&tmp
);
238 hkl_quaternion_times_quaternion(&q
, &tmp
);
240 // copy the vector part of the quaternion in the vector
241 memcpy(v
->data
, &q
.data
[1], sizeof(v
->data
));
245 * @brief check if the hkl_svector is null
246 * @return true if all |elements| are below HKL_EPSILON, false otherwise
249 int hkl_svector_is_null(struct hkl_svector
const * v
)
253 if ( fabs(v
->data
[i
]) > HKL_EPSILON
)