private static float max_error_location(Arc arc, float begin_point_angle, float end_point_angle) { OctahedronUVCoordinates begin_point = new NormalizedCartesianCoordinates(arc.position(begin_point_angle)); OctahedronUVCoordinates end_point = new NormalizedCartesianCoordinates(arc.position(end_point_angle)); float begin = begin_point_angle; float end = end_point_angle; // 2) use binary / bisection search to find the point of maximal error while (end - begin > Precision.delta) { float midpoint = (begin + end) / 2; OctahedronUVCoordinates left_midpoint = new NormalizedCartesianCoordinates(arc.position(midpoint - Precision.delta)); OctahedronUVCoordinates right_midpoint = new NormalizedCartesianCoordinates(arc.position(midpoint + Precision.delta)); float error_left = PlanetariaMath.point_line_distance(begin_point.data, end_point.data, left_midpoint.data); float error_right = PlanetariaMath.point_line_distance(begin_point.data, end_point.data, right_midpoint.data); if (error_left < error_right) //error begin should be replaced since it has less error { begin = midpoint; } else //error end should be replaced since it has less error { end = midpoint; } } return((begin + end) / 2); // return location of max error }
public Discontinuity(Arc arc, NormalizedCartesianCoordinates position) { this.arc = arc; this.position = position.data; this.angle = arc.position_to_angle(this.position); Debug.Assert(Mathf.Abs(angle) <= arc.angle() / 2); }
public override void step() { NormalizedSphericalCoordinates self_position = new NormalizedCartesianCoordinates(self.position); NormalizedSphericalCoordinates target_position = new NormalizedCartesianCoordinates(target.position); NormalizedCartesianCoordinates next_position = new NormalizedSphericalCoordinates(self_position.elevation, target_position.azimuth); self.position = next_position.data; }
private static void add_intersection(Arc arc, NormalizedCartesianCoordinates position) { if (position.data.y <= 0) // FIXME: { if (!discontinuities.ContainsKey(arc)) { discontinuities.Add(arc, new List <Discontinuity>()); } discontinuities[arc].Add(new Discontinuity(arc, position)); } }
public PointPlanetarium(Vector3 point, float radius) { this.point = point; this.radius = radius; // cache for early return Vector3 furthest_point = Vector3.RotateTowards(point, -point, radius, 0.0f); dot_product_threshold = Vector3.Dot(point, furthest_point); pixel_centroids = new NormalizedCartesianCoordinates[0]; }
private static Vector3 grid_snap(Vector3 position) // FIXME: optimize { if (!Event.current.shift) // only snap when shift key is held { return(position); } NormalizedCartesianCoordinates cartesian_position = new NormalizedCartesianCoordinates(position); NormalizedSphericalCoordinates clamped_coordinates = new NormalizedSphericalCoordinates(0, 0); NormalizedSphericalCoordinates desired_coordinates = cartesian_position; for (float row = 0; row <= EditorGlobal.self.rows + 1; ++row) //going over with off by one errors won't ruin the program... { float angle = Mathf.PI * row / (EditorGlobal.self.rows + 1); // TODO: verify the row/columns are not swapped float x = Mathf.Sin(angle); float y = Mathf.Cos(angle); NormalizedSphericalCoordinates test_coordinates = new NormalizedCartesianCoordinates(new Vector3(x, y, 0)); float error = Mathf.Abs(Mathf.DeltaAngle(desired_coordinates.elevation * Mathf.Rad2Deg, test_coordinates.elevation * Mathf.Rad2Deg)); float old_error = Mathf.Abs(Mathf.DeltaAngle(desired_coordinates.elevation * Mathf.Rad2Deg, clamped_coordinates.elevation * Mathf.Rad2Deg)); if (error < old_error) { clamped_coordinates = new NormalizedSphericalCoordinates(test_coordinates.elevation, clamped_coordinates.azimuth); } } for (float column = 0; column < EditorGlobal.self.columns * 2; ++column) //... but going under is bad { float angle = column / EditorGlobal.self.columns * Mathf.PI; float x = Mathf.Sin(angle); float z = Mathf.Cos(angle); NormalizedSphericalCoordinates test_coordinates = new NormalizedCartesianCoordinates(new Vector3(x, 0, z)); float error = Mathf.Abs(Mathf.DeltaAngle(desired_coordinates.azimuth * Mathf.Rad2Deg, test_coordinates.azimuth * Mathf.Rad2Deg)); float old_error = Mathf.Abs(Mathf.DeltaAngle(desired_coordinates.azimuth * Mathf.Rad2Deg, clamped_coordinates.azimuth * Mathf.Rad2Deg)); if (error < old_error) { clamped_coordinates = new NormalizedSphericalCoordinates(clamped_coordinates.elevation, test_coordinates.azimuth); } } cartesian_position = clamped_coordinates; return(cartesian_position.data); }
public ArcPlanetarium(Arc arc, float radius) { this.arc = arc; this.radius = radius; // cache for early return center = arc.position(0); Vector3 vertex = arc.position(arc.angle() / 2); Vector3 furthest_point = Vector3.RotateTowards(vertex, -center, radius, 0.0f); dot_product_threshold = Vector3.Dot(center, furthest_point); SphericalCap lower = arc.floor(-radius); SphericalCap upper = arc.floor(+radius); center_offset = lower.offset + upper.offset; center_range = Mathf.Abs(upper.offset - lower.offset) / 2; pixel_centroids = new NormalizedCartesianCoordinates[0]; }
private static void subdivide(Arc arc, float begin_point_angle, float end_point_angle) { float middle_point_angle = max_error_location(arc, begin_point_angle, end_point_angle); Vector3 begin = arc.position(begin_point_angle); Vector3 middle = arc.position(middle_point_angle); Vector3 end = arc.position(end_point_angle); OctahedronUVCoordinates begin_point = new NormalizedCartesianCoordinates(begin); OctahedronUVCoordinates middle_point = new NormalizedCartesianCoordinates(middle); OctahedronUVCoordinates end_point = new NormalizedCartesianCoordinates(end); if (PlanetariaMath.point_line_distance(begin_point.data, end_point.data, middle_point.data) > Precision.threshold) // if the max error is greater than a threshold, recursively add the left and right halves into the list of lines { subdivide(arc, begin_point_angle, middle_point_angle); subdivide(arc, middle_point_angle, end_point_angle); } else { QuadraticBezierCurve curve = new QuadraticBezierCurve(begin_point.data, middle_point.data, end_point.data); VectorGraphicsWriter.set_edge(curve); } }
protected override void initialize() { Camera camera = this.GetComponentInChildren <Camera>() as Camera; shutter_edges = new GameObject[edges]; for (int edge_index = 0; edge_index < edges; ++edge_index) { shutter_edges[edge_index] = (GameObject)Instantiate(Resources.Load("PrimaryEdge"), new Vector3(0, 0, 2 * PlanetariaCamera.near_clip_plane), Quaternion.Euler(0, 0, edge_index * 360f / edges), camera.transform); #if UNITY_EDITOR shutter_edges[edge_index].transform.localScale = Vector3.one * 4 * PlanetariaMath.cone_radius(2 * PlanetariaCamera.near_clip_plane, camera.fieldOfView * Mathf.Deg2Rad) * Mathf.Sqrt(1 + (camera.aspect * camera.aspect)); #else float x = PlanetariaMath.cone_radius(2 * PlanetariaCamera.near_clip_plane, camera.fieldOfView * Mathf.Deg2Rad); float y = x * camera.aspect; float z = 2 * PlanetariaCamera.near_clip_plane; StereoscopicProjectionCoordinates stereoscopic_projection = new NormalizedCartesianCoordinates(new Vector3(x, y, z)); shutter_edges[edge_index].transform.localScale = Vector3.one * stereoscopic_projection.data.magnitude; // FIXME: VR FOV #endif } }
public NormalizedCartesianCoordinates TransformDirection(NormalizedCartesianCoordinates local_space) { return((NormalizedCartesianCoordinates)internal_transform.TransformDirection(local_space.data)); }
public NormalizedCartesianCoordinates InverseTransformDirection(NormalizedCartesianCoordinates world_space) { return((NormalizedCartesianCoordinates)internal_transform.InverseTransformDirection(world_space.data)); }