UnityMol  0.9.6-875
UnityMol viewer / In developement
OptimalView.cs
Go to the documentation of this file.
1 // ------------------------------------------------------------------------------
2 // <autogenerated>
3 // This code was generated by a tool.
4 // Mono Runtime Version: 4.0.30319.1
5 //
6 // Changes to this file may cause incorrect behavior and will be lost if
7 // the code is regenerated.
8 // </autogenerated>
9 // ------------------------------------------------------------------------------
10 using System;
11 using UnityEngine;
12 using Molecule.Model;
13 using System.Collections;
14 using System.Collections.Generic;
15 using BenTools.Mathematics;
16 using System.Linq;
17 using System.IO;
18 using UI;
19 using GuidedNav;
20 
21 namespace OptimalView
22 {
23  public class OptimalView
24  {
28  public static double Distance2f(Vector pointA, Vector pointB)
29  {
30  return Math.Sqrt(Math.Pow(pointA[0]-pointB[0], 2) + Math.Pow(pointA[1]-pointB[1], 2));
31  }
35  public static double Distance2f(Vector pointA, float[] pointB)
36  {
37  return Math.Sqrt(Math.Pow(pointA[0]-pointB[0], 2) + Math.Pow(pointA[1]-pointB[1], 2));
38  }
42  public static double Distance3f(float[] pointA, float[] pointB)
43  {
44  return Math.Sqrt(Math.Pow(pointA[0]-pointB[0], 2) + Math.Pow(pointA[1]-pointB[1], 2) + Math.Pow(pointA[2]-pointB[2], 2));
45  }
49  public static void GetOptimalPosition (float[] target, float radius)
50  {
51  List<float[]> neighbor_coords = new List<float[]>();
52  ArrayList neighbor_theta_phi = new ArrayList();
53  ArrayList neighbor_theta_phi_plus10 = new ArrayList();
54  ArrayList neighbor_theta_phi_plus20 = new ArrayList();
55  float min_theta = 1000.0f;
56  float max_theta = 0.0f;
57  float min_phi = 1000.0f;
58  float max_phi = 0.0f;
59  int added = 0;
60 
61  // Get all the atoms inside the sphere centered on the target and of the input radius, translate them into polar coordinates
62  for(int i=0; i<MoleculeModel.atomsLocationlist.Count; i++)
63  {
64  double dist = Distance3f(MoleculeModel.atomsLocationlist[i],target);
65  if (dist < radius + 20 && dist > 2.0)
66  {
67  neighbor_coords.Add(MoleculeModel.atomsLocationlist[i]);
68  float[] atom = new float[3];
69  atom[0] = MoleculeModel.atomsLocationlist[i][0] - target[0];
70  atom[1] = MoleculeModel.atomsLocationlist[i][1] - target[1];
71  atom[2] = MoleculeModel.atomsLocationlist[i][2] - target[2];
72  float theta = (float) Math.Acos(atom[2] / dist);
73  float phi = (float) Math.Atan2(atom[1], atom[0]);
74  Vector theta_phi = new Vector(2);
75  theta_phi[0] = theta;
76  theta_phi[1] = phi;
77  neighbor_theta_phi_plus20.Add(theta_phi);
78  added += 1;
79  //Debug.Log (theta_phi);
80  if(theta + (float) Math.PI < 1.5f * Math.PI && phi + (float) Math.PI * 2.0f < 2.0f * Math.PI)
81  {
82  theta_phi = new Vector(2);
83  theta_phi[0] = theta + (float) Math.PI;
84  theta_phi[1] = phi + (float) Math.PI * 2.0f;
85  neighbor_theta_phi_plus20.Add(theta_phi);
86  added += 1;
87  }
88 // Debug.Log (theta_phi);
89  if(theta + (float) Math.PI < 1.5f * Math.PI)
90  {
91  theta_phi = new Vector(2);
92  theta_phi[0] = theta + (float) Math.PI;
93  theta_phi[1] = phi;
94  neighbor_theta_phi_plus20.Add(theta_phi);
95  if (theta + (float) Math.PI > max_theta)
96  max_theta = theta + (float) Math.PI;
97  added += 1;
98  }
99 // Debug.Log (theta_phi);
100  if( phi + (float) Math.PI * 2.0f < 2.0f * Math.PI)
101  {
102  theta_phi = new Vector(2);
103  theta_phi[0] = theta;
104  theta_phi[1] = phi + (float) Math.PI * 2.0f;
105  neighbor_theta_phi_plus20.Add(theta_phi);
106  if (phi + (float) Math.PI * 2.0f > max_phi)
107  max_phi = phi + (float) Math.PI * 2.0f;
108  added += 1;
109  }
110 // Debug.Log (theta_phi);
111  if (theta < min_theta)
112  min_theta = theta;
113  if (phi < min_phi)
114  min_phi = phi;
115  if (dist < radius + 10)
116  {
117  for(int j=1; j<=added; j++){
118  neighbor_theta_phi_plus10.Add(neighbor_theta_phi_plus20[neighbor_theta_phi_plus20.Count-j]);
119  }
120 // neighbor_theta_phi_plus10.Add(neighbor_theta_phi_plus20[neighbor_theta_phi_plus20.Count-3]);
121 // neighbor_theta_phi_plus10.Add(neighbor_theta_phi_plus20[neighbor_theta_phi_plus20.Count-2]);
122 // neighbor_theta_phi_plus10.Add(neighbor_theta_phi_plus20[neighbor_theta_phi_plus20.Count-1]);
123  }
124  if (dist < radius)
125  {
126  for(int j=1; j<=added; j++){
127  neighbor_theta_phi.Add(neighbor_theta_phi_plus20[neighbor_theta_phi_plus20.Count-j]);
128  }
129 // neighbor_theta_phi.Add(neighbor_theta_phi_plus20[neighbor_theta_phi_plus20.Count-4]);
130 // neighbor_theta_phi.Add(neighbor_theta_phi_plus20[neighbor_theta_phi_plus20.Count-3]);
131 // neighbor_theta_phi.Add(neighbor_theta_phi_plus20[neighbor_theta_phi_plus20.Count-2]);
132 // neighbor_theta_phi.Add(neighbor_theta_phi_plus20[neighbor_theta_phi_plus20.Count-1]);
133  }
134  added = 0;
135  }
136  }
137 
138 // Debug.Log (neighbor_theta_phi.GetEnumerator().Current[0]+" "+neighbor_theta_phi.GetEnumerator().Current[1]);
139 // Debug.Log (neighbor_theta_phi[1][0]+" "+neighbor_theta_phi[1][1]);
140 // Debug.Log (neighbor_theta_phi[2][0]+" "+neighbor_theta_phi[2][1]);
141 // Debug.Log (neighbor_theta_phi[3][0]+" "+neighbor_theta_phi[3][1]);
142 
143 // StreamWriter sw = new StreamWriter(@"/Users/trellet/Dev/UnityMol_svn/trunk/Assets/neighbors.txt");
144 
145 //
146 // foreach (Vector neighbor in neighbor_theta_phi)
147 // {
148 // sw.WriteLine(""+neighbor[0]+" "+neighbor[1]);
149 // }
150 // sw.Close ();
151 
152 // int length = neighbor_theta_phi.Count;
153 // for(int i=0; i<length; i++)
154 // {
155 // Vector theta_phi = new Vector(2);
156 // theta_phi[0] = neighbor_theta_phi[i][0]+ (float) Math.PI;
157 // theta_phi[1] = neighbor_theta_phi[i][1]+2*(float) Math.PI;
158 // neighbor_theta_phi.Add (theta_phi);
159 // theta_phi[0] = neighbor_theta_phi[i][0]+(float) Math.PI;
160 // theta_phi[1] = neighbor_theta_phi[i][1];
161 // neighbor_theta_phi.Add (theta_phi);
162 // theta_phi[0] = neighbor_theta_phi[i][0];
163 // theta_phi[1] = neighbor_theta_phi[i][1]+2*(float) Math.PI;
164 // neighbor_theta_phi.Add (theta_phi);
165 // }
166  Debug.Log("Nb of neighbors: "+neighbor_theta_phi.Count);
167  Debug.Log("Min/max theta/phi: "+min_theta+" "+max_theta+" "+min_phi+" "+max_phi);
168 
169  // Compute the Voronoi graph from the neighbors polar coordinates
170  VoronoiGraph result = Fortune.ComputeVoronoiGraph(neighbor_theta_phi);
171  MoleculeModel.atomsLocationlist.OrderBy(x=>x[0]);
172  Debug.Log (result.Vertizes.Count);
173 
174 // StreamWriter sw2 = new StreamWriter(@"/Users/trellet/Dev/UnityMol_svn/trunk/Assets/vertices.txt");
175  BenTools.Data.HashSet temp = new BenTools.Data.HashSet();
176 
177  foreach (Vector vert in result.Vertizes)
178  {
179  if (vert[0] > min_theta && vert[0] < max_theta && vert[1] < max_phi && vert[1] > min_phi)
180  {
181 // sw2.WriteLine(""+vert[0]+" "+vert[1]);
182  temp.Add(vert);
183  }
184  }
185 // sw2.Close ();
187  result.Vertizes = temp;
188 
189  double max_dist = 0.0;
190  float[] best_pos = new float[2];
191 
192  double distance = 0.0;
193  Dictionary<double, float[]> vertices = new Dictionary<double, float[]>();
194 
195  // Find the largest distance between each vertex and the closest point to each of them
197  foreach (VoronoiEdge edge in result.Edges)
198  {
199  //min_dist = 1000.0;
200 
201  if (edge.VVertexA[0] > 0 && edge.VVertexA[0] < Math.PI && edge.VVertexA[1] < Math.PI && edge.VVertexA[1] > -Math.PI)
202  {
203  distance = Distance2f(edge.VVertexA, edge.LeftData);
204  float[] t = new float[2];
205  t[0] = (float) edge.VVertexA[0];
206  t[1] = (float) edge.VVertexA[1];
207  vertices[distance] = t;
208  if (distance > max_dist)
209  {
210  max_dist = distance;
211  best_pos[0] = (float) edge.VVertexA[0];
212  best_pos[1] = (float) edge.VVertexA[1];
213  }
214 
215  }
216  if (edge.VVertexB[0] > 0 && edge.VVertexB[0] < Math.PI && edge.VVertexB[1] < Math.PI && edge.VVertexB[1] > -Math.PI)
217  {
218  distance = Distance2f(edge.VVertexB, edge.LeftData);
219  float[] t = new float[2];
220  t[0] = (float) edge.VVertexB[0];
221  t[1] = (float) edge.VVertexB[1];
222  vertices[distance] = t;
223  if (distance > max_dist)
224  {
225  max_dist = distance;
226  best_pos[0] = (float) edge.VVertexB[0];
227  best_pos[1] = (float) edge.VVertexB[1];
228  }
229  }
230  }
231 
233 
234  // We calculate the voronoi diagram for a larger circle in order to get an optimal camera path while approaching the target
235  result = Fortune.ComputeVoronoiGraph(neighbor_theta_phi_plus10);
236  MoleculeModel.atomsLocationlist.OrderBy(x=>x[0]);
237  Debug.Log (result.Vertizes.Count);
238 
239  double max_dist_plus10 = 0.0f;
240  float[] best_pos_plus10 = new float[2];
241  distance = 0.0f;
242 
243  // Find the largest distance between each vertex and the closest point to each of them
245  foreach (VoronoiEdge edge in result.Edges)
246  {
247  //min_dist = 1000.0;
248  if (Distance2f(edge.VVertexA, best_pos) < Distance2f(edge.VVertexA, edge.LeftData) + max_dist)
249  {
250  if (edge.VVertexA[0] > min_theta && edge.VVertexA[0] < max_theta && edge.VVertexA[1] < max_phi && edge.VVertexA[1] > min_phi)
251  {
252  distance = Distance2f(edge.VVertexA, edge.LeftData);
253  float[] t = new float[2];
254  t[0] = (float) edge.VVertexB[0];
255  t[1] = (float) edge.VVertexB[1];
256  //vertices[distance] = t;
257  if (distance > max_dist_plus10)
258  {
259  max_dist_plus10 = distance;
260  best_pos_plus10[0] = (float) edge.VVertexA[0];
261  best_pos_plus10[1] = (float) edge.VVertexA[1];
262  }
263 
264  }
265  }
266  if (Distance2f(edge.VVertexB, best_pos) < Distance2f(edge.VVertexB, edge.LeftData) + max_dist)
267  {
268  if (edge.VVertexB[0] > min_theta && edge.VVertexB[0] < max_theta && edge.VVertexB[1] < max_phi && edge.VVertexB[1] > min_phi)
269  {
270  distance = Distance2f(edge.VVertexB, edge.LeftData);
271  float[] t = new float[2];
272  t[0] = (float) edge.VVertexB[0];
273  t[1] = (float) edge.VVertexB[1];
274  //vertices[distance] = t;
275  if (distance > max_dist_plus10)
276  {
277  max_dist_plus10 = distance;
278  best_pos_plus10[0] = (float) edge.VVertexB[0];
279  best_pos_plus10[1] = (float) edge.VVertexB[1];
280  }
281  }
282  }
283  }
284 
286 
287  // We calculate the voronoi diagram for a larger circle in order to get an optimal camera path while approaching the target
288  result = Fortune.ComputeVoronoiGraph(neighbor_theta_phi_plus20);
289  MoleculeModel.atomsLocationlist.OrderBy(x=>x[0]);
290  Debug.Log (result.Vertizes.Count);
291 
292  double max_dist_plus20 = 0.0f;
293  float[] best_pos_plus20 = new float[2];
294  distance = 0.0f;
295 
296  // Find the largest distance between each vertex and the closest point to each of them
298  foreach (VoronoiEdge edge in result.Edges)
299  {
300  //min_dist = 1000.0;
301  if (Distance2f(edge.VVertexA, best_pos) < Distance2f(edge.VVertexA, edge.LeftData) + max_dist)
302  {
303  if (edge.VVertexA[0] > min_theta && edge.VVertexA[0] < max_theta && edge.VVertexA[1] < max_phi && edge.VVertexA[1] > min_phi)
304  {
305  distance = Distance2f(edge.VVertexA, edge.LeftData);
306  float[] t = new float[2];
307  t[0] = (float) edge.VVertexA[0];
308  t[1] = (float) edge.VVertexA[1];
309  //vertices[distance] = t;
310  if (distance > max_dist_plus20)
311  {
312  max_dist_plus20 = distance;
313  best_pos_plus20[0] = (float) edge.VVertexA[0];
314  best_pos_plus20[1] = (float) edge.VVertexA[1];
315  }
316 
317  }
318  }
319  if (Distance2f(edge.VVertexB, best_pos) < Distance2f(edge.VVertexB, edge.LeftData) + max_dist)
320  {
321  if (edge.VVertexB[0] > min_theta && edge.VVertexB[0] < max_theta && edge.VVertexB[1] < max_phi && edge.VVertexB[1] > min_phi)
322  {
323  distance = Distance2f(edge.VVertexB, edge.LeftData);
324  float[] t = new float[2];
325  t[0] = (float) edge.VVertexB[0];
326  t[1] = (float) edge.VVertexB[1];
327  //vertices[distance] = t;
328  if (distance > max_dist_plus20)
329  {
330  max_dist_plus20 = distance;
331  best_pos_plus20[0] = (float) edge.VVertexB[0];
332  best_pos_plus20[1] = (float) edge.VVertexB[1];
333  }
334  }
335  }
336  }
337 
338  var list = vertices.Keys.ToList();
339  list.Sort();
340  float[] cartesian = new float[3];
341  Debug.Log("4 best positions");
342 
343  GNParameters.optim_cam_position = new Vector3[4];
344  int count = 4;
345  int nb = list.Count -1;
346  bool exist = false;
347 // StreamWriter sw2 = new StreamWriter(@"/Users/trellet/Dev/UnityMol_svn/trunk/Assets/vertices.txt");
348  while(count > 0)
349  {
350  Debug.Log("count: "+count+"\t nb: "+nb);
351  exist = false;
352  //Debug.Log(list[i]+": "+vertices[list[i]][0]+" "+vertices[list[i]][1]);
353  cartesian[0] = (radius * (float) Math.Sin(vertices[list[nb]][0]) * (float) Math.Cos(vertices[list[nb]][1])) + target[0];
354  cartesian[1] = (radius * (float) Math.Sin(vertices[list[nb]][0]) * (float) Math.Sin(vertices[list[nb]][1])) + target[1];
355  cartesian[2] = (radius * (float) Math.Cos(vertices[list[nb]][0])) + target[2];
356 
357  if(count!=4){
358  for(int k =0; k<(4-count); k++){
359  //if(cartesian[0] == maxCamera.optim_cam_position[k][0] && cartesian[1] == maxCamera.optim_cam_position[k][1])
360  Debug.Log (Vector3.Distance(new Vector3(cartesian[0], cartesian[1], cartesian[2]), GNParameters.optim_cam_position[k]));
361  if(Vector3.Distance(new Vector3(cartesian[0], cartesian[1], cartesian[2]), GNParameters.optim_cam_position[k]) < 5.0){
362  exist = true;
363  break;
364  }
365  }
366  if(exist)
367  nb--;
368  else{
369  GNParameters.optim_cam_position[4-count] = new Vector3(cartesian[0], cartesian[1], cartesian[2]);
370  Debug.Log ("Best pov number "+(count)+" : "+vertices[list[nb]][0]+" "+vertices[list[nb]][1]+"\tDistance: "+list[nb]);
371 // sw2.WriteLine(""+vertices[list[nb]][0]+" "+vertices[list[nb]][1]);
372  count--;
373  nb--;
374 
375  }
376  }
377  else{
378  GNParameters.optim_cam_position[4-count] = new Vector3(cartesian[0], cartesian[1], cartesian[2]);
379  Debug.Log ("Best pov number "+(count)+" : "+vertices[list[nb]][0]+" "+vertices[list[nb]][1]+"\tDistance: "+list[nb]);
380 // sw2.WriteLine(""+vertices[list[nb]][0]+" "+vertices[list[nb]][1]);
381  count--;
382  nb--;
383 
384  }
385  }
386 // sw2.Close();
388 // foreach (Vector vert in result.Vertizes)
389 // {
390 // min_dist = 1000.0;
391 //
392 // foreach (Vector neighbor in neighbor_theta_phi)
393 // {
396 //
397 // double dist = Distance2f(vert, neighbor);
398 //
399 // if (dist < min_dist)
400 // {
401 // min_dist = dist;
402 // point[0] = (float) neighbor[0];
403 // point[1] = (float) neighbor[1];
404 // }
405 // }
406 // if (min_dist > max_dist)
407 // {
408 // max_dist = min_dist;
409 // best_pos[0] = (float) vert[0];
410 // best_pos[1] = (float) vert[1];
411 // best_point[0] = point[0];
412 // best_point[1] = point[1];
413 // }
414 //
415 // }
416  Debug.Log ("Maximum distance: "+max_dist+" "+max_dist_plus10+" "+max_dist_plus20);
417  Debug.Log("Theta and phi: "+best_pos[0]+" "+best_pos[1]);
418  Debug.Log("Theta and phi at 10: "+best_pos_plus10[0]+" "+best_pos_plus10[1]);
419  Debug.Log("Theta and phi at 20: "+best_pos_plus20[0]+" "+best_pos_plus20[1]);
420 
421  Debug.Log("Best position: "+GNParameters.optim_cam_position[0][0]+" "+GNParameters.optim_cam_position[0][1]+" "+GNParameters.optim_cam_position[0][2]);
422  Debug.Log("Best position2: "+GNParameters.optim_cam_position[1][0]+" "+GNParameters.optim_cam_position[1][1]+" "+GNParameters.optim_cam_position[1][2]);
423  Debug.Log("Best position3: "+GNParameters.optim_cam_position[2][0]+" "+GNParameters.optim_cam_position[2][1]+" "+GNParameters.optim_cam_position[2][2]);
424  Debug.Log("Best position4: "+GNParameters.optim_cam_position[3][0]+" "+GNParameters.optim_cam_position[3][1]+" "+GNParameters.optim_cam_position[3][2]);
425 
426  // Place the camera at the new best position and make it face the target
427  GNParameters.optim_target = new Vector3(target[0], target[1], target[2]);
429 
430  GameObject camera = GameObject.Find("LoadBox");
431  UIData.optim_view_start_point = camera.transform.position;
432  UIData.start_time = Time.time;
433  UIData.optim_view = true;
434 
435  }
436  }
437 }
438 
static Vector3 optim_user_cam_pos
3D coordinates of the selected best camera position.
static bool optim_view
Definition: UIData.cs:203
static VoronoiGraph ComputeVoronoiGraph(IEnumerable Datapoints)
A vector class, implementing all interesting features of vectors
Definition: Vector.cs:10
void Add(Vector V)
Add another vector
Definition: Vector.cs:151
static Vector3 optim_target
3D coordinates of the target.
static void GetOptimalPosition(float[] target, float radius)
Get the position with the largest view cone on a specific target and with respect to an input radius ...
Definition: OptimalView.cs:49
static float start_time
Definition: UIData.cs:205
Summary description for Hashset.
Definition: HashSet.cs:9
static double Distance3f(float[] pointA, float[] pointB)
Calculate distance between two float array of length 3.
Definition: OptimalView.cs:42
!WiP Includes FLAGS of GUI.
Definition: UIData.cs:78
The GNParameters class regroups settings used for Guided Navigation and GLIC spreading.
static double Distance2f(Vector pointA, Vector pointB)
Calculate distance between two vectors of length 2.
Definition: OptimalView.cs:28
static Vector3[] optim_cam_position
3D coordinates of the 4 best camera positions.
void Add(object O)
Definition: HashSet.cs:14
static Vector3 optim_view_start_point
Definition: UIData.cs:204
static double Distance2f(Vector pointA, float[] pointB)
Calculate distance between an array and a vector of length 2.
Definition: OptimalView.cs:35
Definition: GUIDisplay.cs:66
static List< float[]> atomsLocationlist
The coordinates of each atom.