# Generate 4 vectors rotated in cardinal directions from a central vector

There is some unit vector, which is a coordinate in a spherical space. It is necessary to obtain from it 4 vectors diverted in different directions (right, left, forward, backward) by a certain number of degrees. For these actions I use the following code:

Vector3 center = point;
Vector3 left = Quaternion.Euler(-30, 0, 0) * center;
Vector3 right = Quaternion.Euler(30, 0, 0) * center;
Vector3 back = Quaternion.Euler(0, 0, -30) * center;
Vector3 front = Quaternion.Euler(0, 0, 30) * center;


The problem is that this works when point is equal or close to Vector3.up. When deviating from the vertical position, the lateral vectors begin to "stick together".

Here is a visualization of what I need: Test code is attached:

using System.Collections;
using UnityEngine;

public class Test : MonoBehaviour
{
public GameObject centerGO;
public GameObject leftGO;
public GameObject rightGO;
public GameObject backGO;
public GameObject frontGO;

ArrayList list = new ArrayList();

void Start()
{
SetCenterPoint(Vector3.up);
}

void Update()
{
DrawDebugRays();

Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;

if (Physics.Raycast(ray, out hit))
{
SetCenterPoint(hit.point);
}
}

void SetCenterPoint(Vector3 point)
{
Vector3 center = point;
Vector3 left = Quaternion.Euler(-30, 0, 0) * center;
Vector3 right = Quaternion.Euler(30, 0, 0) * center;
Vector3 back = Quaternion.Euler(0, 0, -30) * center;
Vector3 front = Quaternion.Euler(0, 0, 30) * center;

centerGO.transform.position = center;
leftGO.transform.position = left;
rightGO.transform.position = right;
backGO.transform.position = back;
frontGO.transform.position = front;

list.Clear();
}

void DrawDebugRays()
{
for (int i = 0; i < list.Count; i++)
{
Color color = Color.red;
switch (i)
{
case 0:
color = Color.green;
break;
case 1:
case 2:
color = Color.blue;
break;
}
Debug.DrawRay(Vector3.zero, (Vector3)list[i], color);
}
}
}

• Hello and welcome to gamedev.se! You'll notice that I removed the link to your Google drive. This is because links like these are transient and are subject to link rot: you'll change your project in the future, making the link irrelevant. Mar 12, 2018 at 0:42
• Because of the hairy ball theorem, there's no way to assign these points in a way that will be globally consistent and smooth between adjacent input vectors all around the sphere (we'll inevitably have a singularity somewhere, where two nearby inputs get significantly different outputs). Is that acceptable for your use case? If not, we can sacrifice global consistency and use some memory of previous history to pick a locally-smooth option, where the output for a given input depends on the route we took to get to that input. Mar 12, 2018 at 3:54
• @DMGregory, For my case, the following conditions are important: the plane BackFront ┴ LeftRight, <BCL = <BCR = <FCR = <FCL = 90*, and the distance from any point to the center should be the same Mar 12, 2018 at 10:52
• That's doable, it's just a matter of if it's OK for, say, the whole quintet to rotate 180° between adjacent inputs. Mar 12, 2018 at 10:55
• @DMGregory, yes, it's quite Mar 12, 2018 at 10:56

Quaternion localSpace = Quaternion.LookRotation(centerDirection);