You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Returns all combinations (``C``) of three candidate point sources from the table of sources `phot` returned by [`Photometry.Aperture.photometry`](@extref), and the computed invariant ``\\mathscr M`` for each according to Eq. 3 from [_Beroiz, M., Cabral, J. B., & Sanchez, B. (2020)_](https://ui.adsabs.harvard.edu/abs/2020A%26C....3200384B/abstract).
5
5
"""
6
6
function_triangle_invariants(phot)
7
-
C =combinations(phot, 3)
8
-
ℳ =map(C) do (pa, pb, pc)
9
-
a, b, c = (
10
-
(pa.ycenter, pa.xcenter),
11
-
(pb.ycenter, pb.xcenter),
12
-
(pc.ycenter, pc.xcenter),
13
-
)
14
-
Ls =sort!([euclidean(a, b), euclidean(b, c), euclidean(a, c)])
15
-
(Ls[3] / Ls[2], Ls[2] / Ls[1])
16
-
end|> stack
7
+
@inlinefunctionsort3(a, b, c)
8
+
a, b =minmax(a, b)
9
+
b, c =minmax(b, c)
10
+
a, b =minmax(a, b)
11
+
return a, b, c # sorted ascending: small, mid, large
12
+
end
13
+
xs = phot.xcenter
14
+
ys = phot.ycenter
15
+
n =length(phot)
16
+
ntriangles =binomial(n, 3)
17
+
ℳ =Matrix{Float64}(undef, 2, ntriangles)
18
+
C =Vector{NTuple{3,Int}}(undef, ntriangles)
19
+
20
+
# Enumerate all combinations(1:n,3) triangles via nested loops over strictly increasing index triples
21
+
# (i < j < l), storing results in pre-allocated C and ℳ indexed by the flat counter k.
22
+
k =0
23
+
for i in1:n-2
24
+
xi, yi = xs[i], ys[i]
25
+
for j in i+1:n-1
26
+
xj, yj = xs[j], ys[j]
27
+
dx_ji, dy_ji = xj - xi, yj - yi
28
+
d2_ji = dx_ji^2+ dy_ji^2# squared distance between sources i and j
29
+
for l in j+1:n
30
+
k +=1
31
+
xl, yl = xs[l], ys[l]
32
+
dx_lj, dy_lj = xl - xj, yl - yj
33
+
dx_li, dy_li = xl - xi, yl - yi
34
+
d2_lj = dx_lj^2+ dy_lj^2# squared distance between sources j and l
35
+
d2_li = dx_li^2+ dy_li^2# squared distance between sources i and l
1. The apex (vertex opposite the longest edge) is last.
26
-
1. The two base vertices are ordered counter-clockwise (positive cross product).
56
+
2. The two base vertices are ordered counter-clockwise (positive cross product).
27
57
28
-
This canonical form is preserved under rotation and translation, so corresponding triangles in two images receive the same vertex permutation and produce geometrically consistent point correspondences.
29
-
"""
30
-
function_canonical_vertex_order(pa, pb, pc)
31
-
xa, ya = pa.xcenter, pa.ycenter
32
-
xb, yb = pb.xcenter, pb.ycenter
33
-
xc, yc = pc.xcenter, pc.ycenter
34
-
35
-
d2_ab = (xb - xa)^2+ (yb - ya)^2
36
-
d2_bc = (xc - xb)^2+ (yc - yb)^2
37
-
d2_ac = (xc - xa)^2+ (yc - ya)^2
38
-
39
-
# Identify the two base vertices (endpoints of longest edge) and the apex
40
-
if d2_ab >= d2_bc && d2_ab >= d2_ac
41
-
v1, v2, apex = pa, pb, pc
42
-
elseif d2_bc >= d2_ab && d2_bc >= d2_ac
43
-
v1, v2, apex = pb, pc, pa
44
-
else
45
-
v1, v2, apex = pa, pc, pb
46
-
end
58
+
This canonical form is preserved under rotation and translation, so corresponding triangles
59
+
in two images receive the same vertex permutation and produce geometrically consistent point
60
+
correspondences.
61
+
62
+
# Examples
63
+
64
+
Consider the triangle with vertices
65
+
66
+
```text
67
+
(1) = (0,4)
68
+
|\
69
+
| \
70
+
4 | \ 5
71
+
| \
72
+
| \
73
+
(0,0) = (2)----(3) = (3,0)
74
+
3
75
+
```
76
+
77
+
The longest edge is (1)-(3), so the apex is vertex (2).
78
+
The initial canonical ordering is therefore (1,3,2).
79
+
80
+
However, this ordering is clockwise in image coordinates, so the
81
+
base vertices are swapped to enforce counter-clockwise winding,
82
+
yielding the final canonical ordering (3,1,2) for these vertices.
47
83
48
-
# Enforce CCW winding so that a rotation does not change the order
0 commit comments