-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fixed bug where -2 direction from points on DB edge returned None; ma…
…de ways to evaluate how different point placement methods look in terms of variation of direction and angle to neighbors
- Loading branch information
Showing
31 changed files
with
278 additions
and
166 deletions.
There are no files selected for viewing
File renamed without changes
File renamed without changes
File renamed without changes
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
File renamed without changes
File renamed without changes
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed
BIN
-59.7 KB
images/PointPlacementMethods/C010100000_to_K010100000_upg1_plot.png
Binary file not shown.
Binary file removed
BIN
-32.7 KB
images/PointPlacementMethods/C010100000_to_K010100000_upg1_steps.png
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# functions relating to measuring angles on the sphere surface | ||
|
||
import math | ||
import numpy as np | ||
|
||
from icosalattice.DistancesOnSphere import distance_great_circle | ||
|
||
|
||
# TODO will probably be good to implement generic methods for solving spherical triangles | ||
# TODO implement measurement of area occupied by a set of points that approximate a 2D region, e.g. a country; use sum of a bunch of triangles for this? | ||
|
||
# https://en.wikipedia.org/wiki/Spherical_trigonometry | ||
|
||
|
||
def measure_angles_on_sphere(xyz_A, xyz_B, xyz_C): | ||
# angle ABC with vertex at B; what angle do the paths AB and BC make when they meet at B? | ||
# assumes radius = 1 | ||
a = distance_great_circle(xyz_B, xyz_C) | ||
b = distance_great_circle(xyz_A, xyz_C) | ||
c = distance_great_circle(xyz_A, xyz_B) | ||
cos_a = np.cos(a) | ||
cos_b = np.cos(b) | ||
cos_c = np.cos(c) | ||
sin_a = np.sin(a) | ||
sin_b = np.sin(b) | ||
sin_c = np.sin(c) | ||
cos_A = (cos_a - cos_b*cos_c)/(sin_b*sin_c) | ||
cos_B = (cos_b - cos_c*cos_a)/(sin_c*sin_a) | ||
cos_C = (cos_c - cos_a*cos_b)/(sin_a*sin_b) | ||
return [np.arccos(cos_A), np.arccos(cos_B), np.arccos(cos_C)] | ||
|
||
|
||
def get_area_of_triangle_on_sphere(xyz1, xyz2, xyz3): | ||
# Girard's theorem | ||
# assumes radius = 1 | ||
angles = measure_angles_on_sphere(xyz1, xyz2, xyz3) | ||
return sum(angles) - np.pi | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# functions relating to measuring distance on sphere surface | ||
|
||
import math | ||
import numpy as np | ||
|
||
|
||
|
||
def convert_distance_3d_to_great_circle(d0, r=1): | ||
theta = 2 * np.arcsin(d0 / (2*r)) | ||
d_gc = r * theta | ||
# assert (0 <= d_gc).all(), f"bad great circle distance {d_gc} from d0={d0}, r={r}" | ||
# assert (d_gc <= np.pi * r).all(), f"bad great circle distance {d_gc} from d0={d0}, r={r}" | ||
# assert ((d_gc > d0) | (abs(d_gc - d0) < 1e-9)).all(), f"shortest distance should be a straight line, but got great-circle {d_gc} from Euclidean {d0}" | ||
# print(f"d0 = {d0}, r = {r} -> great circle distance {d_gc}") | ||
return d_gc | ||
# return (np.vectorize(lambda d: UnitSpherePoint.convert_distance_3d_to_great_circle_single_value(d, radius=radius)))(d0) | ||
|
||
|
||
def convert_distance_great_circle_to_3d(d_gc, r=1): | ||
theta = d_gc / r | ||
d0 = 2 * r * np.sin(theta) | ||
assert 0 <= d0 <= 2*r, f"bad 3d distance {d0} from d_gc={d_gc}, r={r}" | ||
assert d0 <= d_gc, "shortest distance should be a straight line" | ||
return d0 | ||
|
||
|
||
def distance_3d(xyz1, xyz2): | ||
return np.linalg.norm(xyz1 - xyz2) | ||
|
||
|
||
def distance_great_circle(xyz1, xyz2, r=1): | ||
d0 = distance_3d(xyz1, xyz2) | ||
return convert_distance_3d_to_great_circle(d0, r) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
from functools import reduce | ||
import numpy as np | ||
import matplotlib.pyplot as plt | ||
|
||
import icosalattice.GeneratePointCodes as gpc | ||
import icosalattice.PlotPointLocations as ppl | ||
from icosalattice.PointPaths import get_point_path, get_stepwise_path_distances_and_angles_2d | ||
from icosalattice.PlotPaths import plot_distances_and_angles_2d | ||
import icosalattice.PeelCoordinates as pe | ||
from icosalattice.Adjacency import get_neighbors_of_point_code | ||
from icosalattice.AnglesOnSphere import measure_angles_on_sphere | ||
from icosalattice.DistancesOnSphere import distance_great_circle | ||
|
||
|
||
|
||
def plot_point_distribution_on_one_face(func_pc_to_xyz, iterations=4): | ||
# observe how the points lie along lines or curves on the face | ||
# pcs = gpc.get_all_point_codes_from_ancestor_at_iteration(ancestor_pc="C", iterations=6) | ||
pcs = gpc.get_all_point_codes_on_face_at_iteration(face_name="CAKX", iterations=iterations, with_edges=True, with_trailing_zeros=True) | ||
ppl.plot_point_codes_on_half_peel_face_planes(pcs, face_name="CAKX", func_pc_to_xyz=func_pc_to_xyz, with_labels=False) | ||
# for future self searching for code that made plots: | ||
# CAKX_i4_{method}.png | ||
|
||
|
||
def plot_point_distribution_on_northern_half_peels(func_pc_to_xyz, iterations=6): | ||
pcs = reduce((lambda x,y: x+y), [gpc.get_all_point_codes_from_ancestor_at_iteration(ancestor_pc=apc, iterations=iterations) for apc in "CEGIK"]) + ["A"] | ||
ppl.plot_point_codes_on_sphere_3d(pcs, func_pc_to_xyz=func_pc_to_xyz, with_labels=False) | ||
|
||
|
||
def plot_trajectory_between_two_points_on_face_plane(pc_init, pc_final, direction, func_pc_to_xyz): | ||
pcs = get_point_path(pc_init, pc_final, direction)[:-1] | ||
ppl.plot_point_codes_on_half_peel_face_planes(pcs, face_name="CAKX", func_pc_to_xyz=func_pc_to_xyz, with_labels=False) | ||
ls, ds = pe.get_adjusted_peel_coordinates_of_point_codes_on_face(pcs, face_name="CAKX", func_pc_to_xyz=func_pc_to_xyz) | ||
distances, angles = get_stepwise_path_distances_and_angles_2d(ls, ds) | ||
plot_distances_and_angles_2d(distances, angles) | ||
# for future self searching for code that made plots: | ||
# C010100000_to_K010100000_steps_{method}.png | ||
# {pc_init}_to_{pc_final}_steps_{method}.png | ||
|
||
|
||
def report_neighbor_angle_and_distance_statistics(func_pc_to_xyz, iterations=6): | ||
pcs = gpc.get_all_point_codes_at_iteration(iterations=iterations, with_trailing_zeros=True) | ||
pc_to_xyz = {pc: func_pc_to_xyz(pc) for pc in pcs} | ||
angles = [] | ||
|
||
# debug: finding aberrantly large angles | ||
angles_larger_than_72 = {} | ||
|
||
distances = [] | ||
for i, pc in enumerate(pcs): | ||
if i % 1000 == 0: | ||
print(f"getting distances and angles: {i = } / {len(pcs)}") | ||
xyz0 = pc_to_xyz[pc] | ||
neighbors = get_neighbors_of_point_code(pc) | ||
# print(pc, neighbors) | ||
these_angles_deg = [] | ||
these_distances = [] | ||
|
||
# there is double counting and redundant computation going on here | ||
# (since the distances are used in computing the angles, we compute the same angles more than once, etc.) | ||
# but I don't care right now unless it takes very long to finish | ||
|
||
for i in range(len(neighbors)): | ||
n1 = neighbors[i] | ||
n2 = neighbors[(i+1) % len(neighbors)] | ||
xyz1 = pc_to_xyz[n1] | ||
xyz2 = pc_to_xyz[n2] | ||
angle1, angle0, angle2 = measure_angles_on_sphere(xyz1, xyz0, xyz2) | ||
angle0_deg = angle0 * 180/np.pi | ||
|
||
# debug: finding aberrantly large angles | ||
if angle0_deg > 72 + 1e-9: | ||
a = round(angle0_deg, 6) | ||
if a not in angles_larger_than_72: | ||
angles_larger_than_72[a] = [] | ||
angles_larger_than_72[a].append((n1, pc, n2)) | ||
|
||
distance = distance_great_circle(xyz0, xyz1) | ||
these_angles_deg.append(angle0_deg) | ||
these_distances.append(distance) | ||
angles += these_angles_deg | ||
distances += these_distances | ||
|
||
print("\nlarge angles:\n" + ("\n".join(f" {a:f} deg: {tup}" for a, tups in sorted(angles_larger_than_72.items(), reverse=True) for tup in tups) if len(angles_larger_than_72) > 0 else "(none)") + "\n") | ||
|
||
print(f"{min(angles) = :f}") | ||
print(f"mean(angles) = {np.mean(angles):f}") | ||
print(f"median(angles) = {np.median(angles):f}") | ||
print(f"{max(angles) = :f}\n") | ||
|
||
print(f"{min(distances) = :f}") | ||
print(f"mean(distances) = {np.mean(distances):f}") | ||
print(f"median(distances) = {np.median(distances):f}") | ||
print(f"{max(distances) = :f}\n") | ||
|
||
plt.hist(angles, bins=100) | ||
plt.title("angles") | ||
plt.show() | ||
# for future self searching for code that made plots: | ||
# neighbor_angle_distribution_{method}.png | ||
|
||
plt.hist(distances, bins=100) | ||
plt.title("distances") | ||
plt.show() | ||
# for future self searching for code that made plots: | ||
# neighbor_distance_distribution_{method}.png |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.