HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonModerate

Algorithm to get an arbitrary perpendicular vector

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
arbitraryalgorithmperpendiculargetvector

Problem

Is there a more efficient/direct way to find an arbitrary perpendicular vector of another vector?

def perpendicular_vector(v):
    r""" Finds an arbitrary perpendicular vector to *v*. """

    a, b = random.random(), random.random()
    if not iszero(v.z):
        x, y, z = v.x, v.y, v.z
    elif not iszero(v.y):
        x, y, z = v.x, v.z, v.y
    elif not iszero(v.x):
        x, y, z = v.y, v.z, v.x
    else:
        raise ValueError('zero-vector')

    c = (- x * a - y * b) / z

    if not iszero(v.z):
        return Vector(a, b, c)
    elif not iszero(v.y):
        return Vector(a, c, b)
    elif not iszero(v.x):
        return Vector(b, c, a)

Solution

The cross product of two vectors is perpendicular to both vectors, unless both vectors are parallel. So you could simply take the cross product of your first vector with (1, 0, 0), unless it is parallel to (1, 0, 0), in which case you could use (0, 1, 0). If you use lists rather than dedicated classes with attributes and are willing to use numpy, this gets ridiculously short:

import numpy as np

def perpendicular_vector(v):
    if v[1] == 0 and v[2] == 0:
        if v[0] == 0:
            raise ValueError('zero vector')
        else:
            return np.cross(v, [0, 1, 0]]
    return np.cross(v, [1, 0, 0])

Code Snippets

import numpy as np

def perpendicular_vector(v):
    if v[1] == 0 and v[2] == 0:
        if v[0] == 0:
            raise ValueError('zero vector')
        else:
            return np.cross(v, [0, 1, 0]]
    return np.cross(v, [1, 0, 0])

Context

StackExchange Code Review Q#43928, answer score: 10

Revisions (0)

No revisions yet.