5 #include <hkl/hkl-vector.h>
6 #include <hkl/hkl-matrix.h>
7 #include <hkl/hkl-quaternion.h>
9 void hkl_vector_init(HklVector
*v
, double x
, double y
, double z
)
16 void hkl_vector_fprintf(FILE *file
, HklVector
const *v
)
18 fprintf(file
, "|%f, %f, %f|", v
->data
[0], v
->data
[1], v
->data
[2]);
21 int hkl_vector_cmp(HklVector
const *v
, HklVector
const *v1
)
26 if ( fabs(v
->data
[i
] - v1
->data
[i
]) > HKL_EPSILON
)
32 extern int hkl_vector_is_opposite(HklVector
const *v
, HklVector
const *v1
)
37 if ( fabs(v
->data
[i
] + v1
->data
[i
]) > HKL_EPSILON
)
42 void hkl_vector_minus_vector(HklVector
*v
, HklVector
const *v1
)
46 v
->data
[i
] -= v1
->data
[i
];
49 void hkl_vector_div_double(HklVector
*v
, double const d
)
56 void hkl_vector_times_double(HklVector
*v
, double const d
)
63 void hkl_vector_times_vector(HklVector
*v
, HklVector
const *v1
)
67 v
->data
[i
] *= v1
->data
[i
];
70 void hkl_vector_times_smatrix(HklVector
*v
, HklMatrix
const *m
)
75 v
->data
[0] = tmp
.data
[0] *m
->data
[0][0] + tmp
.data
[1] *m
->data
[1][0] + tmp
.data
[2] *m
->data
[2][0];
76 v
->data
[1] = tmp
.data
[0] *m
->data
[0][1] + tmp
.data
[1] *m
->data
[1][1] + tmp
.data
[2] *m
->data
[2][1];
77 v
->data
[2] = tmp
.data
[0] *m
->data
[0][2] + tmp
.data
[1] *m
->data
[1][2] + tmp
.data
[2] *m
->data
[2][2];
80 double hkl_vector_sum(HklVector
const *v
)
82 return v
->data
[0] + v
->data
[1] + v
->data
[2];
85 double hkl_vector_scalar_product(HklVector
const *v
, HklVector
const *v1
)
91 scalar
+= v
->data
[i
] *v1
->data
[i
];
95 void hkl_vector_vectorial_product(HklVector
*v
, HklVector
const *v1
)
100 v
->data
[0] = tmp
.data
[1] *v1
->data
[2] - tmp
.data
[2] *v1
->data
[1];
101 v
->data
[1] = tmp
.data
[2] *v1
->data
[0] - tmp
.data
[0] *v1
->data
[2];
102 v
->data
[2] = tmp
.data
[0] *v1
->data
[1] - tmp
.data
[1] *v1
->data
[0];
106 double hkl_vector_angle(HklVector
const *v
, HklVector
const *v1
)
114 norm_v
= hkl_vector_norm2(v
);
115 norm_v1
= hkl_vector_norm2(v1
);
117 // check the validity of the parameters
118 assert(norm_v
> HKL_EPSILON
);
119 assert(norm_v1
> HKL_EPSILON
);
121 norm
= norm_v
*norm_v1
;
123 cos_angle
= hkl_vector_scalar_product(v
, v1
) / norm
;
125 // problem with round
129 if (cos_angle
<= -1 )
132 angle
= acos(cos_angle
);
137 *@brief normalize a hkl_vector
138 *@return true if the hkl_vector can be normalized, false otherwise
139 *@todo check the status
141 int hkl_vector_normalize(HklVector
*v
)
143 int status
= HKL_FAIL
;
145 double norm
= hkl_vector_norm2(v
);
146 if ( norm
> HKL_EPSILON
)
148 hkl_vector_div_double(v
, norm
);
149 status
= HKL_SUCCESS
;
155 int hkl_vector_is_colinear(HklVector
const *v
, HklVector
const *v1
)
160 hkl_vector_vectorial_product(&tmp
, v1
);
161 if (hkl_vector_norm2(&tmp
) < HKL_EPSILON
)
168 void hkl_vector_randomize(HklVector
*v
)
170 v
->data
[0] = -1 + 2 *rand()/(RAND_MAX
+1.0);
171 v
->data
[1] = -1 + 2 *rand()/(RAND_MAX
+1.0);
172 v
->data
[2] = -1 + 2 *rand()/(RAND_MAX
+1.0);
175 void hkl_vector_randomize_vector(HklVector
*v
, HklVector
const *v1
)
178 hkl_vector_randomize(v
);
179 while (!hkl_vector_cmp(v
, v1
));
182 void hkl_vector_randomize_vector_vector(HklVector
*v
, HklVector
const *v1
, HklVector
const *v2
)
185 hkl_vector_randomize(v
);
186 while (!hkl_vector_cmp(v
, v1
) || !hkl_vector_cmp(v
, v2
));
189 /**rotate a vector around another vector with an angle */
190 void hkl_vector_rotated_around_vector(HklVector
*v
, HklVector
const *axe
, double angle
)
192 double c
= cos(angle
);
193 double s
= sin(angle
);
198 hkl_vector_normalize(&axe_n
);
202 v
->data
[0] = (c
+ (1 - c
) *axe_n
.data
[0] *axe_n
.data
[0]) *tmp
.data
[0];
203 v
->data
[0] += ((1 - c
) *axe_n
.data
[0] *axe_n
.data
[1] - axe_n
.data
[2] *s
) *tmp
.data
[1];
204 v
->data
[0] += ((1 - c
) *axe_n
.data
[0] *axe_n
.data
[2] + axe_n
.data
[1] *s
) *tmp
.data
[2];
206 v
->data
[1] = ((1 - c
) *axe_n
.data
[0] *axe_n
.data
[1] + axe_n
.data
[2] *s
) *tmp
.data
[0];
207 v
->data
[1] += (c
+ (1 - c
) *axe_n
.data
[1] *axe_n
.data
[1]) *tmp
.data
[1];
208 v
->data
[1] += ((1 - c
) *axe_n
.data
[1] *axe_n
.data
[2] - axe_n
.data
[0] *s
) *tmp
.data
[2];
210 v
->data
[2] = ((1 - c
) *axe_n
.data
[0] *axe_n
.data
[2] - axe_n
.data
[1] *s
) *tmp
.data
[0];
211 v
->data
[2] += ((1 - c
) *axe_n
.data
[1] *axe_n
.data
[2] + axe_n
.data
[0] *s
) *tmp
.data
[1];
212 v
->data
[2] += (c
+ (1 - c
) *axe_n
.data
[2] *axe_n
.data
[2]) *tmp
.data
[2];
215 double hkl_vector_norm2(HklVector
const *v
)
217 return sqrt(v
->data
[0] *v
->data
[0] + v
->data
[1] *v
->data
[1] + v
->data
[2] *v
->data
[2]);
221 * apply a quaternion rotation to a vector
224 void hkl_vector_rotated_quaternion(HklVector
*v
, HklQuaternion
const *qr
)
229 // compute qr * qv * *qr
231 hkl_quaternion_from_vector(&tmp
, v
);
233 hkl_quaternion_times_quaternion(&q
, &tmp
);
235 hkl_quaternion_conjugate(&tmp
);
236 hkl_quaternion_times_quaternion(&q
, &tmp
);
238 // copy the vector part of the quaternion in the vector
239 memcpy(v
->data
, &q
.data
[1], sizeof(v
->data
));
243 * @brief check if the hkl_vector is null
244 * @return true if all |elements| are below HKL_EPSILON, false otherwise
247 int hkl_vector_is_null(HklVector
const *v
)
251 if ( fabs(v
->data
[i
]) > HKL_EPSILON
)