# How do you select 3d lines in Vectrosity by clicking?

i have created lines using the VectorLine.SetLine3D function and would like to be able to select a line by clicking on it.
I am using c# and would like to be able to do this on iOS and web platforms.
Thanks in advance and thanks for the answers to questions others have asked, for i have benefited as well.

Here is a bit of code that demonstrates how it can be done mathematically. What is needed is the minimum distance between a ray and a line segment, since you need to cast a ray into the scene for a perspective camera. This can be solved as single function mathematically. But I just went out and grabbed the [Math3d class from the Unity Wiki,][1] and did it in three function calls (per segment).

1. Find the closest point on the ray to the line defined by the two segment points
2. Find the closest point on the line segment to the point from step 1.
3. Find the distance between the points in step 1 and 2.

If the distance is below the selection threshold, and if it is closer than any other distance found, it becomes the best candidate.

Note the sample code uses a LineRender. It generates a number of points in 3D space. When a line is selected, the code places a marker sphere at both ends of the segment. Note since the lines are in 3D space, the spheres will be at different distance from the camera and therefore usually very different in size. You could make the code more efficient by combining and simplify the function calls, but with 10,000 segments I found no lag when selecting (on my desktop).

``````using UnityEngine;
using System.Collections;

[RequireComponent (typeof (LineRenderer))]
public class SelectSegment : MonoBehaviour {

public int ptCount = 25;
public float selectionThreshold = 0.05f;

private  Vector3[] points;
private Transform marker1;
private Transform marker2;

void Start () {
LineRenderer lr = GetComponent<LineRenderer>();
lr.SetWidth(0.1f, 0.1f);
lr.SetVertexCount(ptCount);

points = new Vector3[ptCount];
for (int i = 0; i < ptCount; i++) {
points _= Random.insideUnitSphere * 6.0f;_
``````

_ lr.SetPosition(i, points*);_
_
}*_

* marker1 = GameObject.CreatePrimitive(PrimitiveType.Sphere).transform;*
* marker1.localScale = new Vector3(.15f, .15f, .15f);*
* marker2 = GameObject.CreatePrimitive(PrimitiveType.Sphere).transform;*
* marker1.localScale = new Vector3(.15f, .15f, .15f);*
* marker1.renderer.enabled = false;*
* marker2.renderer.enabled = false;*
* }*

* void Update () {*
* if (Input.GetMouseButtonDown (0)) {*
* int iSelect = AttemptSelect();*
* if (iSelect != -1) {*
* marker1.transform.position = points[iSelect];*
* marker1.renderer.enabled = true;*
* marker2.transform.position = points[iSelect +1];*
* marker2.renderer.enabled = true;*
* }*
* else {*
* marker1.renderer.enabled = false;*
* marker2.renderer.enabled = false;*
* }*
* }*
* }*

* // Returns -1 if it did not find any lines within the threshold,*
* // or it returns the index of the first point in the closest segment*
* int AttemptSelect() {*
* Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);*

* int iSelect = -1;*
* float closestYet = Mathf.Infinity;*

* for (int i = 0; i < points.Length-1; i++) {*
* Vector3 closest1;*
* Vector3 closest2;*
if (Math3d.ClosestPointsOnTwoLines(out closest1, out closest2, ray.origin, ray.direction, points_, points[i+1] - points*)) {
Vector3 v = Math3d.ProjectPointOnLineSegment(points, points[i+1], closest1);
float dist = (v - closest1).magnitude;
if (dist < closestYet && dist < selectionThreshold) {
iSelect = i;
closestYet = dist;
}
}
}
return iSelect;
}
}_

[1]: http://wiki.unity3d.com/index.php/3d_Math_functions*