send a tag suggestion

which tags should be associated with each other?


why should these tags be associated?

Use the form below to provide more context.

#vectors


i'm currently dealing with the classic "whenever i look up/down my character controller slows down" problem in my engine. for the Jolt Physics character controller i have to supply a movement direction vector, but i'm not sure how to calculate it properly without getting this issue

currently i'm just multiplying the camera's orientation quaternion by (0.0f, 0.0f, -1.0f) for a forward vector and (1.0f, 0.0f, 0.0f) for a right vector, then using that to create the direction vector. obviously this is wrong somehow since the camera pitch is affecting the movement speed, but i'm not sure what the proper way is. if it helps i'm also using the GLM library for math stuff



So, clojures vectors behave in a lot of scenarios like associative data structures like records or maps with the indices of the elements as the keys.

get v n will give you the nth element in a vector v

assoc v i e will associate element e at index i in vector v

a famous confuser for newcomers is probably the contains? function which only answers the question if an element is available under a certain key. The famous quote being "contains? is not a rummager". Funnily though it will work on vectors, but do the unexpected thing and look if the vector is large enough to support the index.

So for all intents and purposes vectors in clojure are just associative datastructures, right?
Well, yes. Except where they aren't.

The counterpart for assoc, dissoc, irritatingly doesn't work on vectors and only does work on maps. I find this particularly irritating, as the only real way to "remove" elements from vectors at some index is subvec which does something else entirely. So this sort of behaviour on vectors is sorely missing.

That being said, here is a simple redefinition of dissoc in clojure so that it also works on vectors.

(defn- dissoc-vec
  ([v index]
   (if (get v index)
     (vec (concat (subvec v 0 index)
                  (subvec v (inc index))))
     v))
  ([v key & ks]
   (let [n (count v)]
     (loop [v v key key ks ks]
       (let [diff (- (count v) n)
             ret (dissoc-vec v (+ diff key))]
         (if ks
           (recur ret (first ks) (next ks))
           ret))))))
(def dissoc (if| (->| (unapply| first) vector?) dissoc-vec clojure.core/dissoc))
syntax highlighting by codehost


i usually forget the way to load vectors with adv. simd intrinsics, since i don't use them often. i also usually forget sshl with negated shift values is how you can do an arithmetic right shift on a by-vector-element basis, which, in hindsight makes sense i guess, since sshr only has an immediate variant

now i have a place to look if i forget again

#include <arm_neon.h>

#include <cstdio>
#include <cstring>

int main() {
    const int vals[4] = {int(0x80000000), 0x00000001, int(0xFF000000), 0};
    const int shifts[4] = {-1, -2, -8, -10};

    const int32x4_t values = vld1q_s32(vals);
    const int32x4_t shift = vld1q_s32(shifts);
    const int32x4_t result = vshlq_s32(values, shift);

    int out[4];
    std::memcpy(&out, &result, sizeof(out));

    // Result: 0x00000000 | 0xFFFF0000 | 0x00000000 | 0xC0000000
    std::printf("0x%08X | 0x%08X | 0x%08X | 0x%08X",
                out[3], out[2], out[1], out[0]);
    return 0;
}