Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 34 additions & 2 deletions lib/turf/boolean_concave.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,39 @@

# :nodoc:
module Turf
def boolean_concave(*args)
raise NotImplementedError
# frozen_string_literal: true

# Takes a polygon and returns true or false as to whether it is concave or not.
#
# @function
# @param [Feature<Polygon>, Polygon] polygon to be evaluated
# @return [Boolean] true/false
# @example
# convex_polygon = polygon([[[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]])
#
# boolean_concave(convex_polygon)
# # => false
def boolean_concave(polygon)
coords = get_geom(polygon)[:coordinates]
return false if coords[0].length <= 4

sign = nil
n = coords[0].length - 1

(0...n).each do |i|
dx1 = coords[0][(i + 2) % n][0] - coords[0][(i + 1) % n][0]
dy1 = coords[0][(i + 2) % n][1] - coords[0][(i + 1) % n][1]
dx2 = coords[0][i][0] - coords[0][(i + 1) % n][0]
dy2 = coords[0][i][1] - coords[0][(i + 1) % n][1]
zcrossproduct = (dx1 * dy2) - (dy1 * dx2)

if i.zero?
sign = zcrossproduct.positive?
elsif sign != zcrossproduct.positive?
return true
end
end

false
end
end
38 changes: 38 additions & 0 deletions test/turf_boolean_concave_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# frozen_string_literal: true

require "test_helper"

class TurfBooleanConcaveTest < Minitest::Test
def test_is_concave_fixtures
# True Fixtures
Dir.glob(File.join(__dir__, "boolean_concave", "true", "*.geojson")).each do |filepath|
name = File.basename(filepath, ".geojson")
geojson = JSON.parse(File.read(filepath))
feature = geojson[:features][0]
assert(Turf.boolean_concave(feature), "[true] #{name}")
end

# False Fixtures
Dir.glob(File.join(__dir__, "boolean_concave", "false", "*.geojson")).each do |filepath|
name = File.basename(filepath, ".geojson")
geojson = JSON.parse(File.read(filepath))
feature = geojson[:features][0]
refute(Turf.boolean_concave(feature), "[false] #{name}")
end
end

def test_is_concave_geometry_types
poly = Turf.polygon([
[
[0, 0],
[0, 1],
[1, 1],
[1, 0],
[0, 0],
],
])

assert_equal(false, Turf.boolean_concave(poly), "Feature")
assert_equal(false, Turf.boolean_concave(poly[:geometry]), "Geometry Object")
end
end
20 changes: 20 additions & 0 deletions test/turf_concave/false/3vertices.geojson
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[0, 0],
[1, 1],
[1, 0],
[0, 0]
]
]
}
}
]
}
22 changes: 22 additions & 0 deletions test/turf_concave/false/diamond.geojson
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[0.69488525390625, 1.1754546449158993],
[0.263671875, 0.9118267425981088],
[0.56854248046875, 0.4312093081601601],
[0.96954345703125, 0.771766211876697],
[0.83221435546875, 1.016182073033441],
[0.69488525390625, 1.1754546449158993]
]
]
}
}
]
}
21 changes: 21 additions & 0 deletions test/turf_concave/false/square.geojson
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[0, 0],
[0, 1],
[1, 1],
[1, 0],
[0, 0]
]
]
}
}
]
}
22 changes: 22 additions & 0 deletions test/turf_concave/true/polygon.geojson
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[0, 0],
[1, 0],
[1, 1],
[0.5, 0.5],
[0, 1],
[0, 0]
]
]
}
}
]
}
28 changes: 28 additions & 0 deletions test/turf_concave/true/polygon2.geojson
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[0.85418701171875, 1.06286628163273],
[0.46966552734375, 0.7909904981540058],
[0.6619262695312499, 0.5712795966325395],
[0.77178955078125, 0.856901647439813],
[0.736083984375, 0.8514090937773031],
[0.6591796875, 0.8129610018708315],
[0.6921386718749999, 0.884364296613886],
[0.9173583984375001, 0.8898568022677679],
[1.07391357421875, 0.8129610018708315],
[1.0876464843749998, 0.9392889790847924],
[1.0052490234375, 1.0271666545523288],
[0.85418701171875, 1.06286628163273]
]
]
}
}
]
}