给定点 1 和点 2 之间的线,点 3 的角度变化是多少?

Given the line between points 1 and 2, what is the change in angle to point 3?

我在 Oracle 18c 中有折线 table。

  ASSET_ID VERTEX_NUM          X          Y ANGLE_CHANGE
---------- ---------- ---------- ---------- ------------
        10          1     118.56        3.8         null
        10          2     118.62       1.03         null
        10          3     121.93       1.03            ?

        20          1     123.59       1.19         null
        20          2     124.21       1.02         null
        20          3     124.85        .96            ?
        20          4     125.49       1.01            ?
        20          5     126.11       1.16            ?
        20          6      126.7       1.41            ?
        20          7     127.24       1.75            ?
        20          8     127.26       2.16            ? --I chose to put this point in the screenshot just because the change in angle is large. So it was easy to illustrate what I'm looking for (lots of room for markup).
        20          9     127.36       2.56            ?
        20         10     127.52       2.94            ?
        20         11     127.75       3.29            ?
        20         12     128.03       3.59            ?

        30          1     129.84       1.26         null
        30          2     133.26       2.88         null

使用 SQL,我想确定点到点的“角度变化”。


问题:

如何计算点之间的角度?

换句话说,给定点 1 和点 2 之间的一条线,到点 3 的角度变化是多少?

db<>fiddle

用符号X01 = X1 - X0,

Θ = atan2(Y12, X12) - atan2(Y01, X01)

所以

tan(Θ) = (Y12.X01 - Y01.X12) / (X12.X01 + Y12.Y01)

这是我想到的。最低限度测试。

select
    asset_id
from
    (
    select
        c.*,
        case
            when abs(angle  -  lag (angle,1) over (partition by asset_id, part_num order by asset_id, part_num, vertex_num)  )   between 8.5 and 11.5 then 'Y'
        end as densified_angle    
    from
        (
        select
            b.*,
            atan2(y-y_prev, x-x_prev)*180/3.14159 as angle
        from
            (
            select
                asset_id,
                part_num,
                vertex_num,
                x,
                y,
                lag (x,1) over (partition by asset_id, part_num order by asset_id, part_num, vertex_num) as x_prev,
                lag (y,1) over (partition by asset_id, part_num order by asset_id, part_num, vertex_num) as y_prev
            from
                infrastr.bc_test_vw a
            ) b    
        ) c  
    ) d    
match_recognize (
         order by asset_id, part_num, vertex_num
         all rows per match
         pattern(y{3,})
         define 
         y as (densified_angle='Y')
       ) mr
group by
    asset_id

该查询在外部查询中有一些额外的逻辑——查找至少连续三个顶点的线——其中顶点之间的角度在 8.5 到 11.5 之间。这是我正在处理的一个特定用例,我试图找到 densified.

相关:Determine if line has true curves via SQL (SDE.ST_GEOMETRY in Oracle)


灵感来自 similar post on superuser.com 中的答案,但 Excel。