From f4ebed36de90796e3f4da55d608ab405bf76cdf2 Mon Sep 17 00:00:00 2001 From: chuan Date: Fri, 31 Oct 2025 22:19:26 +0800 Subject: [PATCH 1/2] seis/utilmeca: stabilize NP selection near P/T dip tie with epsilon guard to prevent quadrant flips --- src/seis/utilmeca.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/seis/utilmeca.c b/src/seis/utilmeca.c index 31142a1bc8f..9d1bcae2784 100644 --- a/src/seis/utilmeca.c +++ b/src/seis/utilmeca.c @@ -910,13 +910,21 @@ void meca_axe2dc (struct SEIS_AXIS T, struct SEIS_AXIS P, struct SEIS_NODAL_PLAN } if (p2 < 0.0) p2 += 360.0; - NP1->dip = d1; NP1->str = p1; - NP2->dip = d2; NP2->str = p2; - - im = 1; - if (P.dip > T.dip) im = -1; - NP1->rake = meca_computed_rake2 (NP2->str, NP2->dip, NP1->str, NP1->dip, im); - NP2->rake = meca_computed_rake2 (NP1->str, NP1->dip, NP2->str, NP2->dip, im); + NP1->dip = d1; NP1->str = p1; + NP2->dip = d2; NP2->str = p2; + + /* Epsilon-aware tie-break: avoid quadrant swap when P.dip ≈ T.dip */ + if (P.dip > T.dip + SEIS_EPSILON) { + im = -1; + } else if (P.dip < T.dip - SEIS_EPSILON) { + im = 1; + } else { + /* |P.dip - T.dip| <= SEIS_EPSILON: deterministic choice */ + im = -1; + } + + NP1->rake = meca_computed_rake2 (NP2->str, NP2->dip, NP1->str, NP1->dip, im); + NP2->rake = meca_computed_rake2 (NP1->str, NP1->dip, NP2->str, NP2->dip, im); } void meca_dc2axe (st_me meca, struct SEIS_AXIS *T, struct SEIS_AXIS *N, struct SEIS_AXIS *P) { From ce3658b89a3c0134849259c8380867ec1af759d9 Mon Sep 17 00:00:00 2001 From: He Xingchen Date: Mon, 3 Nov 2025 12:15:42 +0800 Subject: [PATCH 2/2] Update src/seis/utilmeca.c Co-authored-by: Dongdong Tian --- src/seis/utilmeca.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/seis/utilmeca.c b/src/seis/utilmeca.c index 9d1bcae2784..c6210c05eff 100644 --- a/src/seis/utilmeca.c +++ b/src/seis/utilmeca.c @@ -913,7 +913,7 @@ void meca_axe2dc (struct SEIS_AXIS T, struct SEIS_AXIS P, struct SEIS_NODAL_PLAN NP1->dip = d1; NP1->str = p1; NP2->dip = d2; NP2->str = p2; - /* Epsilon-aware tie-break: avoid quadrant swap when P.dip ≈ T.dip */ + /* Epsilon-aware tie-break: avoid quadrant swap when P.dip is almost equal T.dip */ if (P.dip > T.dip + SEIS_EPSILON) { im = -1; } else if (P.dip < T.dip - SEIS_EPSILON) {