Skip to content

Instantly share code, notes, and snippets.

@sofakingworld
Last active August 22, 2016 19:47
Show Gist options
  • Save sofakingworld/e505b7ceb315ab4ca0b270b07b718809 to your computer and use it in GitHub Desktop.
Save sofakingworld/e505b7ceb315ab4ca0b270b07b718809 to your computer and use it in GitHub Desktop.
TSQL (MS SQL) Polygon issues :)
CREATE function [dbo].[BelongsToPolygon](@id int, @X1 float, @Y1 float) returns int
as begin
declare @result int
declare @maxx float
if exists(select 1 from P where polygon_id=@id and x=@X1 and y=@Y1) return 1
declare @point table(id int, x float, y float)
insert into @point (id,x,y) select point_id, x, y from P
where polygon_id = @id order by point_id asc
if @@ROWCOUNT<3 set @result = 0
else
begin
select @maxx = MAX(x) from @point
select @res = case when sum(dbo.LineSegmentCollision(@x1,@y1,@maxx+1,@y1,p1.x,p1.y,p2.x,p2.y))%2=0 then 'No' else 'Yes' end from @point p1
left join @point p2 on p1.id+1 = p2.id or (p1.id = (select MAX(id) from @point) and p2.id = (select MIN(id) from @point))
end
return @res
end
--CALCULATING PERIMETR OF POLYGON
CREATE function [dbo].[calcPerimetr](@id int) returns float
as begin
declare @result float
declare @point table(id int, x float, y float)
insert into @point (id,x,y) select point_id, x, y from P
where polygon_id = @id order by point_id asc
if @@ROWCOUNT<3 set @result = 0
else select @result = sum(sqrt(square(p2.x-p1.x)+SQUARE(p2.y-p1.y))) from @point p1
left join @point p2 on p1.id+1 = p2.id or (p1.id = (select MAX(id) from @point) and p2.id = (select MIN(id) from @point))
return @res
end
--CALCULATING SQUARE OF POLYGON
CREATE function [dbo].[calcSquare](@id int) returns float
as begin
declare @result float
declare @point table(id int, x float, y float)
insert into @point (id,x,y) select point_id, x, y from P
where polygon_id = @id order by point_id asc
if @@ROWCOUNT<3 set @result = 0
else select @result = abs(IsNull(NullIf((sum(p1.x*p2.y)-SUM(p1.y*p2.x)),0),(sum(p1.x*p2.y)+SUM(p1.y*p2.x)))/2) from @point p1
left join @point p2 on p1.id+1 = p2.id or (p1.id = (select MAX(id) from @point) and p2.id = (select MIN(id) from @point))
return @result
end
--CHECKING THE CROSSING TWO SEGMENTS
--SEGMENT1 consists of two points A1(Ax1,Ay1) and B1(Bx1,By1)
--SEGMENT2 consists of two points A2(Ax2,Ay2) and B2(Bx2,By2)
CREATE function [dbo].[LineSegmentCollision](@AX1 float, @AY1 float, @AX2 float, @AY2 float, @BX1 float, @BY1 float, @BX2 float, @BY2 float) returns int
as begin
return case when (((@BX2-@BX1)*(@AY1-@BY1)-(@BY2-@BY1)*(@AX1-@BX1))*
((@BX2-@BX1)*(@AY2-@BY1)-(@BY2-@BY1)*(@AX2-@BX1)))<0 and
(((@AX2-@AX1)*(@BY1-@AY1)-(@AY2-@AY1)*(@BX1-@AX1))*
((@AX2-@AX1)*(@BY2-@AY1)-(@AY2-@AY1)*(@BX2-@AX1)))<0 then 1 else 0 end
end
Is a table containing identifiers and the vertex coordinates of figures.
P (Polygon_id int, point_id int, x float, y float)
Points are listed sequentially in a clockwise or counter- clockwise
1. It is necessary to write a function that returns the area of a selected polygon
2. It is necessary to write a function that returns the perimeter of the selected polygon
3. Check whether the point is on the specified coordinates inside the polygon
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment