PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Tôi có thể sử dụng các hàm Postgres để tìm các điểm bên trong một hình chữ nhật xoay có kích thước cố định không?

Tôi đã kết thúc bằng cách tạo các đỉnh hình chữ nhật, xoay các đỉnh đó, sau đó so sánh diện tích của hình chữ nhật (không đổi) với diện tích của 4 hình tam giác được tạo ra bằng cách bao gồm cả điểm kiểm tra.

Kỹ thuật này dựa trên câu trả lời phân tích cú pháp :

Các hình chữ nhật được xác định bởi

  • Đ dưới cùng bên trái (-x / 2, -y / 2)

  • B trên cùng bên trái (-x / 2, + y / 2)

  • C trên cùng bên phải (+ x / 2, + y / 2)

  • Đ dưới cùng bên phải (+ x / 2, -y / 2)

Sau đó, mã này sẽ kiểm tra xem điểm (qx, qy) có nằm bên trong một hình chữ nhật có chiều rộng x=10 không và chiều cao y=20 , được quay xung quanh điểm gốc (0,0) một góc có phạm vi từ 0 đến 180, 10 độ.

Đây là mã. Mất 9 phút để kiểm tra 750 nghìn điểm, vì vậy vẫn còn chỗ để cải thiện. Ngoài ra, nó có thể được chạy song song khi tôi nâng cấp lên 9.6

with t as (select 10*0.5 as x, 20*0.5 as y, 17.0 as qx, -3.0 as qy)

select 
    z.angle
    -- ABC area
    --,abs(0.5*(z.ax*(z.by-z.cy)+z.bx*(z.cy-z.ay)+z.cx*(z.ay-z.by)))

    -- CDA area
    --,abs(0.5*(z.cx*(z.dy-z.ay)+z.dx*(z.ay-z.cy)+z.ax*(z.cy-z.dy)))

    -- ABCD area
    ,abs(0.5*(z.ax*(z.by-z.cy)+z.bx*(z.cy-z.ay)+z.cx*(z.ay-z.by))) + abs(0.5*(z.cx*(z.dy-z.ay)+z.dx*(z.ay-z.cy)+z.ax*(z.cy-z.dy))) as abcd_area

    -- ABQ area
    --,abs(0.5*(z.ax*(z.by-z.qx)+z.bx*(z.qy-z.ay)+z.qx*(z.ay-z.by)))

    -- BCQ area
    --,abs(0.5*(z.bx*(z.cy-z.qx)+z.cx*(z.qy-z.by)+z.qx*(z.by-z.cy)))

    -- CDQ area
    --,abs(0.5*(z.cx*(z.dy-z.qx)+z.dx*(z.qy-z.cy)+z.qx*(z.cy-z.dy)))

    -- DAQ area
    --,abs(0.5*(z.dx*(z.ay-z.qx)+z.ax*(z.qy-z.dy)+z.qx*(z.dy-z.ay)))

    -- total area of triangles with question point (ABQ + BCQ + CDQ + DAQ)
    ,abs(0.5*(z.ax*(z.by-z.qx)+z.bx*(z.qy-z.ay)+z.qx*(z.ay-z.by)))
        + abs(0.5*(z.bx*(z.cy-z.qx)+z.cx*(z.qy-z.by)+z.qx*(z.by-z.cy)))
        + abs(0.5*(z.cx*(z.dy-z.qx)+z.dx*(z.qy-z.cy)+z.qx*(z.cy-z.dy)))
        + abs(0.5*(z.dx*(z.ay-z.qx)+z.ax*(z.qy-z.dy)+z.qx*(z.dy-z.ay))) as point_area

from
(
SELECT 
    a.id as angle
    -- bottom left (A)
    ,(-t.x) * cos(radians(a.id)) - (-t.y) * sin(radians(a.id)) as ax
    ,(-t.x) * sin(radians(a.id)) + (-t.y) * cos(radians(a.id)) as ay
    --top left (B)
    ,(-t.x) * cos(radians(a.id)) - (t.y) * sin(radians(a.id)) as bx
    ,(-t.x) * sin(radians(a.id)) + (t.y) * cos(radians(a.id)) as by
    --top right (C)
    ,(t.x) * cos(radians(a.id)) - (t.y) * sin(radians(a.id)) as cx
    ,(t.x) * sin(radians(a.id)) + (t.y) * cos(radians(a.id)) as cy
    --bottom right (D)
    ,(t.x) * cos(radians(a.id)) - (-t.y) * sin(radians(a.id)) as dx
    ,(t.x) * sin(radians(a.id)) + (-t.y) * cos(radians(a.id)) as dy

    -- point to check (Q)
    ,t.qx as qx
    ,t.qy as qy
FROM generate_series(0,180,10) AS a(id), t
) z
;

kết quả sau đó là

angle;abcd_area;point_area
0;200;340
10;200;360.6646055963
20;200;373.409049054212
30;200;377.846096908265
40;200;373.84093170467
50;200;361.515248361426
60;200;341.243556529821
70;200;313.641801308188
80;200;279.548648061772
90;200;240
*100;200;200*
*110;200;200*
*120;200;200*
*130;200;200*
*140;200;200*
150;200;237.846096908265
160;200;277.643408923024
170;200;312.04311584956
180;200;340

Khi đó các góc quay 100, 110, 120, 130 và 140 độ bao gồm điểm kiểm tra (được chỉ ra bằng * )




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tại sao postgis của tôi không sử dụng chỉ mục trên trường hình học?

  2. Đặt phụ thuộc c3p0 ở đâu trong Tomcat Container

  3. SQL:Tìm chuỗi chung dài nhất giữa các hàng

  4. Sự khác biệt giữa pg_table_size, pg_relation_size &pg_total_relation_size là gì? (PostgreSQL)

  5. Không thể kết nối với Postgres qua PHP nhưng có thể kết nối từ dòng lệnh và PgAdmin trên máy khác