|
给猫咪转了个章,顺便贴下我的SQL:
with c as ( ---- 9个点及其坐标
select x,y,rownum cid
from (select level x from dual connect by level<=3)
,(select level y from dual connect by level<=3)
)
,m as ( ----- 两两的点构成的线段, 两个端点命名为A和B
select c1.x A_x,c1.y A_y,c2.x B_x,c2.y B_y
,c1.cid||c2.cid mid
from c c1,c c2
WHERE c1.cid<c2.cid
)
,crossing AS ( ----- 所有交叉的成对线段
SELECT m1.mid cr1,m2.mid cr2
FROM m m1,
(SELECT mid,A_x C_x,A_y C_y,B_x D_x,B_y D_y FROM m) m2 ---- 第一个线段AB,第二个线段改名CD, 方便套用算法
WHERE m1.mid<>m2.mid
AND ((C_x-A_x)*(D_y-A_y)-(D_x-A_x)*(C_y-A_y))*((C_x-B_x)*(D_y-B_y)-(D_x-B_x)*(C_y-B_y))<=0
AND ((A_x-C_x)*(B_y-C_y)-(B_x-C_x)*(A_y-C_y))*((A_x-D_x)*(B_y-D_y)-(B_x-D_x)*(A_y-D_y))<=0
)
,tr AS ( ---- 所有三角形及其三条边
SELECT c1.cid||c2.cid||c3.cid as tid
,c1.cid||c2.cid mid1
,c1.cid||c3.cid mid2
,c2.cid||c3.cid mid3
FROM c c1,c c2,c c3
WHERE c1.cid<c2.cid
AND c2.cid<c3.cid
AND (c2.y-c1.y)*(c3.x-c1.x)<>(c3.y-c1.y)*(c2.x-c1.x)
)
,trm AS ( ---- 每个三角形拆成三行,一条边一行
SELECT tid,DECODE(n,1,mid1,2,mid2,3,mid3) mid
FROM tr,(SELECT LEVEL n FROM DUAL CONNECT BY LEVEL<=3)
)
,ctrm AS (---所有交叉或触碰的成对三角形
SELECT DISTINCT trm1.tid tid1,trm2.tid tid2
FROM trm trm1,trm trm2,crossing
WHERE trm1.tid<trm2.tid
AND trm1.mid=crossing.cr1
AND trm2.mid=crossing.cr2
)
SELECT tr1.tid tid1,tr2.tid tid2
FROM tr tr1,tr tr2
WHERE tr1.tid<tr2.tid
MINUS
SELECT tid1,tid2 FROM ctrm
;
178 rows selected.
|
|