mirror of https://github.com/KLayout/klayout.git
More intuitive DRC specification of 'projection_limits' with 'projecting' and a condition
This commit is contained in:
parent
c5859cd957
commit
80d0229b7c
|
|
@ -96,7 +96,20 @@ module DRC
|
|||
|
||||
def projection_limits(*args)
|
||||
self._context("projection_limits") do
|
||||
DRCProjectionLimits::new(*args)
|
||||
if args.size == 0
|
||||
raise("At least one argument is required")
|
||||
end
|
||||
res = DRCProjectionLimits::new(*args)
|
||||
res.description = "projection_limits"
|
||||
res
|
||||
end
|
||||
end
|
||||
|
||||
def projecting
|
||||
self._context("projecting") do
|
||||
res = DRCProjectionLimits::new
|
||||
res.description = "projecting"
|
||||
res
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -2312,6 +2325,30 @@ CODE
|
|||
v
|
||||
end
|
||||
|
||||
def _make_value_with_nil(v)
|
||||
if v == nil
|
||||
return v
|
||||
end
|
||||
self._check_numeric(v)
|
||||
self._prep_value(v)
|
||||
end
|
||||
|
||||
def _make_area_value_with_nil(v)
|
||||
if v == nil
|
||||
return v
|
||||
end
|
||||
self._check_numeric(v)
|
||||
self._prep_value_area(v)
|
||||
end
|
||||
|
||||
def _make_numeric_value_with_nil(v)
|
||||
if v == nil
|
||||
return v
|
||||
end
|
||||
self._check_numeric(v)
|
||||
v
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def _make_string(v)
|
||||
|
|
|
|||
|
|
@ -344,12 +344,12 @@ module DRC
|
|||
if args.size == 1
|
||||
a = args[0]
|
||||
if a.is_a?(Range)
|
||||
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::Region, :with_#{f}, @engine._prep_value_area(a.first), @engine._prep_value_area(a.last), #{inv.inspect}))
|
||||
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::Region, :with_#{f}, @engine._make_area_value_with_nil(a.begin), @engine._make_area_value_with_nil(a.end), #{inv.inspect}))
|
||||
else
|
||||
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::Region, :with_#{f}, @engine._prep_value_area(a), #{inv.inspect}))
|
||||
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::Region, :with_#{f}, @engine._make_area_value(a), #{inv.inspect}))
|
||||
end
|
||||
elsif args.size == 2
|
||||
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::Region, :with_#{f}, @engine._prep_value_area(args[0]), @engine._prep_value_area(args[1]), #{inv.inspect}))
|
||||
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::Region, :with_#{f}, @engine._make_area_value_with_nil(args[0]), @engine._make_area_value_with_nil(args[1]), #{inv.inspect}))
|
||||
else
|
||||
raise("Invalid number of arguments (1 or 2 expected)")
|
||||
end
|
||||
|
|
@ -500,12 +500,12 @@ CODE
|
|||
if args.size == 1
|
||||
a = args[0]
|
||||
if a.is_a?(Range)
|
||||
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::Region, :with_#{f}, @engine._prep_value(a.first), @engine._prep_value(a.last), #{inv.inspect}))
|
||||
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::Region, :with_#{f}, @engine._make_value_with_nil(a.begin), @engine._make_value_with_nil(a.end), #{inv.inspect}))
|
||||
else
|
||||
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::Region, :with_#{f}, @engine._prep_value(a), #{inv.inspect}))
|
||||
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::Region, :with_#{f}, @engine._make_value(a), #{inv.inspect}))
|
||||
end
|
||||
elsif args.size == 2
|
||||
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::Region, :with_#{f}, @engine._prep_value(args[0]), @engine._prep_value(args[1]), #{inv.inspect}))
|
||||
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::Region, :with_#{f}, @engine._make_value_with_nil(args[0]), @engine._make_value_with_nil(args[1]), #{inv.inspect}))
|
||||
else
|
||||
raise("Invalid number of arguments (1 or 2 expected)")
|
||||
end
|
||||
|
|
@ -600,7 +600,7 @@ CODE
|
|||
if args.size == 1
|
||||
a = args[0]
|
||||
if a.is_a?(Range)
|
||||
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::Region, :with_#{f}, @engine._make_numeric_value(a.first), @engine._make_numeric_value(a.last), #{inv.inspect}))
|
||||
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::Region, :with_#{f}, @engine._make_numeric_value_with_nil(a.begin), @engine._make_numeric_value_with_nil(a.end), #{inv.inspect}))
|
||||
else
|
||||
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::Region, :with_#{f}, @engine._make_numeric_value(a), #{inv.inspect}))
|
||||
end
|
||||
|
|
@ -655,12 +655,12 @@ CODE
|
|||
if args.size == 1
|
||||
a = args[0]
|
||||
if a.is_a?(Range)
|
||||
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::Edges, :with_#{f}, @engine._prep_value(a.first), @engine._prep_value(a.last), #{inv.inspect}))
|
||||
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::Edges, :with_#{f}, @engine._make_value_with_nil(a.begin), @engine._make_value_with_nil(a.end), #{inv.inspect}))
|
||||
else
|
||||
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::Edges, :with_#{f}, @engine._prep_value(a), #{inv.inspect}))
|
||||
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::Edges, :with_#{f}, @engine._make_value(a), #{inv.inspect}))
|
||||
end
|
||||
elsif args.size == 2
|
||||
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::Edges, :with_#{f}, @engine._prep_value(args[0]), @engine._prep_value(args[1]), #{inv.inspect}))
|
||||
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::Edges, :with_#{f}, @engine._make_value_with_nil(args[0]), @engine._make_value_with_nil(args[1]), #{inv.inspect}))
|
||||
else
|
||||
raise("Invalid number of arguments (1 or 2 expected)")
|
||||
end
|
||||
|
|
@ -733,7 +733,7 @@ CODE
|
|||
if args.size == 1
|
||||
a = args[0]
|
||||
if a.is_a?(Range)
|
||||
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, result_class, :with_angle, a.first, a.last, #{inv.inspect}))
|
||||
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, result_class, :with_angle, a.begin, a.end, #{inv.inspect}))
|
||||
else
|
||||
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, result_class, :with_angle, a, #{inv.inspect}))
|
||||
end
|
||||
|
|
@ -779,7 +779,7 @@ CODE
|
|||
def rounded_corners(inner, outer, n)
|
||||
@engine._context("rounded_corners") do
|
||||
requires_region
|
||||
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::Region, :rounded_corners, @engine._prep_value(inner), @engine._prep_value(outer), n))
|
||||
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::Region, :rounded_corners, @engine._make_value(inner), @engine._make_value(outer), n))
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -798,7 +798,7 @@ CODE
|
|||
def smoothed(d)
|
||||
@engine._context("smoothed") do
|
||||
requires_region
|
||||
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::Region, :smoothed, @engine._prep_value(d)))
|
||||
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::Region, :smoothed, @engine._make_value(d)))
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -1365,9 +1365,9 @@ CODE
|
|||
@engine._context("ongrid") do
|
||||
requires_region
|
||||
if args.size == 1
|
||||
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::EdgePairs, :grid_check, @engine._prep_value(args[0]), @engine._prep_value(args[0])))
|
||||
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::EdgePairs, :grid_check, @engine._make_value(args[0]), @engine._make_value(args[0])))
|
||||
elsif args.size == 2
|
||||
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::EdgePairs, :grid_check, @engine._prep_value(args[0]), @engine._prep_value(args[1])))
|
||||
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::EdgePairs, :grid_check, @engine._make_value(args[0]), @engine._make_value(args[1])))
|
||||
else
|
||||
raise("Invalid number of arguments (1 or 2 expected)")
|
||||
end
|
||||
|
|
@ -1406,14 +1406,13 @@ CODE
|
|||
requires_region
|
||||
gx = gy = 0
|
||||
if args.size == 1
|
||||
gx = gy = @engine._prep_value(args[0])
|
||||
gx = gy = @engine._make_value(args[0])
|
||||
elsif args.size == 2
|
||||
gx = @engine._prep_value(args[0])
|
||||
gy = @engine._prep_value(args[1])
|
||||
gx = @engine._make_value(args[0])
|
||||
gy = @engine._make_value(args[1])
|
||||
else
|
||||
raise("Invalid number of arguments (1 or 2 expected)")
|
||||
end
|
||||
aa = args.collect { |a| @engine._prep_value(a) }
|
||||
if :#{f} == :snap && @engine.is_tiled?
|
||||
# in tiled mode, no modifying versions are available
|
||||
self.data = @engine._tcmd(self.data, 0, self.data.class, :snapped, gx, gy)
|
||||
|
|
@ -2606,7 +2605,7 @@ CODE
|
|||
def #{f}(length, fraction = 0.0)
|
||||
@engine._context("#{f}") do
|
||||
requires_edges
|
||||
length = @engine._prep_value(length)
|
||||
length = @engine._make_value(length)
|
||||
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::Edges, :#{f}, length, fraction))
|
||||
end
|
||||
end
|
||||
|
|
@ -2657,16 +2656,16 @@ CODE
|
|||
av = [ 0, 0, 0, 0, false ]
|
||||
args.each_with_index do |a,i|
|
||||
if a.is_a?(Hash)
|
||||
a[:begin] && av[0] = @engine._prep_value(a[:begin])
|
||||
a[:end] && av[1] = @engine._prep_value(a[:end])
|
||||
a[:out] && av[2] = @engine._prep_value(a[:out])
|
||||
a[:in] && av[3] = @engine._prep_value(a[:in])
|
||||
a[:begin] && av[0] = @engine._make_value(a[:begin])
|
||||
a[:end] && av[1] = @engine._make_value(a[:end])
|
||||
a[:out] && av[2] = @engine._make_value(a[:out])
|
||||
a[:in] && av[3] = @engine._make_value(a[:in])
|
||||
a[:joined] && av[4] = true
|
||||
elsif i < 4
|
||||
if !a.is_a?(1.class) && !a.is_a?(Float)
|
||||
raise("Invalid type for argument #" + (i+1).to_s)
|
||||
end
|
||||
av[i] = @engine._prep_value(a)
|
||||
av[i] = @engine._make_value(a)
|
||||
elsif i == 4
|
||||
if a.is_a?(DRCJoinFlag)
|
||||
av[i] = a.value
|
||||
|
|
@ -2715,7 +2714,7 @@ CODE
|
|||
def #{f}(dist)
|
||||
@engine._context("#{f}") do
|
||||
requires_edges
|
||||
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::Region, :#{f}, @engine._prep_value(dist)))
|
||||
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::Region, :#{f}, @engine._make_value(dist)))
|
||||
end
|
||||
end
|
||||
CODE
|
||||
|
|
@ -2999,6 +2998,10 @@ CODE
|
|||
# @li @b projection_limits(min, max) or projection_limits(min .. max) @/b:
|
||||
# this option makes the check only consider edge pairs whose projected length on
|
||||
# each other is more or equal than min and less than max @/li
|
||||
# @li @b projecting (in condition) @/b: This specification is equivalent to "projection_limits"
|
||||
# but is more intuitive, as "projecting" is written with a condition, like
|
||||
# "projecting < 2.um". Available operators are: "==", "<", "<=", ">" and ">=".
|
||||
# Double-bounded ranges are also available, like: "0.5 <= projecting < 2.0".
|
||||
# @li @b transparent @/b: performs the check without shielding (polygon layers only) @/li
|
||||
# @li @b shielded @/b: performs the check with shielding (polygon layers only) @/li
|
||||
# @/ul
|
||||
|
|
@ -3333,13 +3336,12 @@ CODE
|
|||
elsif a.is_a?(DRCLayer)
|
||||
other = a
|
||||
elsif a.is_a?(DRCProjectionLimits)
|
||||
minp = @engine._prep_value(a.min)
|
||||
maxp = @engine._prep_value(a.max)
|
||||
(minp, maxp) = a.get_limits(@engine)
|
||||
elsif a.is_a?(DRCShielded)
|
||||
shielded = a.value
|
||||
elsif a.is_a?(Float) || a.is_a?(1.class)
|
||||
value && raise("Value already specified")
|
||||
value = @engine._prep_value(a)
|
||||
value = @engine._make_value(a)
|
||||
else
|
||||
raise("Parameter #" + n.to_s + " does not have an expected type")
|
||||
end
|
||||
|
|
@ -3542,7 +3544,7 @@ CODE
|
|||
values = []
|
||||
args.each do |a|
|
||||
if a.is_a?(1.class) || a.is_a?(Float)
|
||||
v = @engine._prep_value(a)
|
||||
v = @engine._make_value(a)
|
||||
v.abs > dist && dist = v.abs
|
||||
values.push(v)
|
||||
elsif a.is_a?(DRCSizingMode)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,157 @@
|
|||
|
||||
module DRC
|
||||
|
||||
# A base class for implementing ranges that can be put into a condition
|
||||
module DRCComparable
|
||||
|
||||
attr_accessor :reverse
|
||||
attr_accessor :original
|
||||
attr_accessor :lt, :le, :gt, :ge
|
||||
attr_accessor :description
|
||||
attr_accessor :mode_or_supported
|
||||
attr_accessor :mode_or
|
||||
|
||||
def _init_comparable
|
||||
self.reverse = false
|
||||
self.original = nil
|
||||
self.le = nil
|
||||
self.ge = nil
|
||||
self.lt = nil
|
||||
self.gt = nil
|
||||
self.gt = nil
|
||||
self.description = ""
|
||||
self.mode_or_supported = false
|
||||
self.mode_or = false
|
||||
end
|
||||
|
||||
def _check_bounds
|
||||
if ! self.mode_or && (self.lt || self.le) && (self.gt || self.ge)
|
||||
epsilon = 1e-10
|
||||
lower = self.ge ? self.ge - epsilon : self.gt + epsilon
|
||||
upper = self.le ? self.le + epsilon : self.lt - epsilon
|
||||
if lower > upper - epsilon
|
||||
raise("'" + self.description + "': lower bound is larger than upper bound")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def set_lt(value)
|
||||
(self.lt || self.le) && raise("'" + self.description + "' already has an upper bound of " + ("%.12g" % (self.lt || self.le)))
|
||||
self.lt = value
|
||||
self._check_bounds
|
||||
end
|
||||
|
||||
def set_le(value)
|
||||
(self.lt || self.le) && raise("'" + self.description + "' already has an upper bound of " + ("%.12g" % (self.lt || self.le)))
|
||||
self.le = value
|
||||
self._check_bounds
|
||||
end
|
||||
|
||||
def set_gt(value)
|
||||
(self.gt || self.ge) && raise("'" + self.description + "' already has an lower bound of " + ("%.12g" % (self.gt || self.ge)))
|
||||
self.gt = value
|
||||
self._check_bounds
|
||||
end
|
||||
|
||||
def set_ge(value)
|
||||
(self.gt || self.ge) && raise("'" + self.description + "' already has an lower bound of " + ("%.12g" % (self.gt || self.ge)))
|
||||
self.ge = value
|
||||
self._check_bounds
|
||||
end
|
||||
|
||||
def coerce(something)
|
||||
reversed = self.dup
|
||||
reversed.reverse = true
|
||||
reversed.original = self
|
||||
[ reversed, something ]
|
||||
end
|
||||
|
||||
def _self_or_original
|
||||
return (self.original || self).dup
|
||||
end
|
||||
|
||||
def !=(other)
|
||||
if self.respond_to?(:inverted)
|
||||
res = self.==(other).inverted
|
||||
else
|
||||
if !self.mode_or_supported
|
||||
raise("!= operator is not allowed for '" + self.description + "'")
|
||||
end
|
||||
if !(other.is_a?(Float) || other.is_a?(Integer))
|
||||
raise("!= operator needs a numerical argument for '" + self.description + "' argument")
|
||||
end
|
||||
res = self._self_or_original
|
||||
res.mode_or = true
|
||||
res.set_lt(other)
|
||||
res.set_gt(other)
|
||||
end
|
||||
res
|
||||
end
|
||||
|
||||
def ==(other)
|
||||
if !(other.is_a?(Float) || other.is_a?(Integer))
|
||||
raise("== operator needs a numerical argument for '" + self.description + "' argument")
|
||||
end
|
||||
res = self._self_or_original
|
||||
res.set_le(other)
|
||||
res.set_ge(other)
|
||||
return res
|
||||
end
|
||||
|
||||
def <(other)
|
||||
if !(other.is_a?(Float) || other.is_a?(Integer))
|
||||
raise("< operator needs a numerical argument for '" + self.description + "' argument")
|
||||
end
|
||||
res = self._self_or_original
|
||||
if reverse
|
||||
res.set_gt(other)
|
||||
else
|
||||
res.set_lt(other)
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
def <=(other)
|
||||
if !(other.is_a?(Float) || other.is_a?(Integer))
|
||||
raise("<= operator needs a numerical argument for '" + self.description + "' argument")
|
||||
end
|
||||
res = self._self_or_original
|
||||
if reverse
|
||||
res.set_ge(other)
|
||||
else
|
||||
res.set_le(other)
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
def >(other)
|
||||
if !(other.is_a?(Float) || other.is_a?(Integer))
|
||||
raise("> operator needs a numerical argument for '" + self.description + "' argument")
|
||||
end
|
||||
res = self._self_or_original
|
||||
if reverse
|
||||
res.set_lt(other)
|
||||
else
|
||||
res.set_gt(other)
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
def >=(other)
|
||||
if !(other.is_a?(Float) || other.is_a?(Integer))
|
||||
raise(">= operator needs a numerical argument for '" + self.description + "' argument")
|
||||
end
|
||||
res = self._self_or_original
|
||||
if reverse
|
||||
res.set_le(other)
|
||||
else
|
||||
res.set_ge(other)
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# A wrapper for a named value which is stored in
|
||||
# a variable for delayed execution
|
||||
class DRCVar
|
||||
|
|
@ -106,28 +257,55 @@ module DRC
|
|||
# This class is used to identify projection limits for DRC
|
||||
# functions
|
||||
class DRCProjectionLimits
|
||||
attr_accessor :min
|
||||
attr_accessor :max
|
||||
|
||||
include DRCComparable
|
||||
|
||||
def initialize(*a)
|
||||
if a.size > 2 || a.size == 0
|
||||
raise("A projection limits specification requires a maximum of two values and at least one argument")
|
||||
|
||||
_init_comparable
|
||||
|
||||
if a.size > 2
|
||||
|
||||
raise("A projection limits specification requires a maximum of two values")
|
||||
|
||||
elsif a.size == 1
|
||||
|
||||
if !a[0].is_a?(Range) || (!a[0].min.is_a?(Float) && !a[0].min.is_a?(1.class))
|
||||
raise("A projection limit requires an interval of two length values or two individual length values")
|
||||
end
|
||||
self.min = a[0].min
|
||||
self.max = a[0].max
|
||||
|
||||
self.set_ge(a[0].min)
|
||||
self.set_lt(a[0].max)
|
||||
|
||||
elsif a.size == 2
|
||||
|
||||
if a[0] && !a[0].is_a?(Float) && !a[0].is_a?(1.class)
|
||||
raise("First argument to a projection limit must be either nil or a length value")
|
||||
end
|
||||
if a[1] && !a[1].is_a?(Float) && !a[1].is_a?(1.class)
|
||||
raise("Second argument to a projection limit must be either nil or a length value")
|
||||
end
|
||||
self.min = a[0]
|
||||
self.max = a[1]
|
||||
|
||||
self.set_ge(a[0])
|
||||
self.set_lt(a[1])
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def get_limits(engine)
|
||||
|
||||
if ! self.le && ! self.ge && ! self.lt && ! self.gt
|
||||
raise("No constraint given for projection limits (supply values or place inside a condition)")
|
||||
end
|
||||
|
||||
min = self.ge ? engine._make_value(self.ge) : (self.gt ? engine._make_value(self.gt) + 1 : 0)
|
||||
max = self.le ? engine._make_value(self.le) + 1 : (self.lt ? engine._make_value(self.lt) : nil)
|
||||
|
||||
[ min, max ]
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# A wrapper for an input for the antenna check
|
||||
|
|
|
|||
|
|
@ -14,6 +14,29 @@ l1.output(1, 0)
|
|||
l2.output(2, 0)
|
||||
l3.output(3, 0)
|
||||
|
||||
|
||||
# Self-test "projection_limits"
|
||||
|
||||
def self_test(id, a, b)
|
||||
a == b || raise(id + ": self-test failed (" + a.inspect + " != " + b.inspect + ")")
|
||||
end
|
||||
|
||||
l = projection_limits(0..2.0)
|
||||
self_test("projection_limits(1)", l.get_limits(self), [ 0, 2000 ])
|
||||
l = projecting < 2.0
|
||||
self_test("projection_limits(2)", l.get_limits(self), [ 0, 2000 ])
|
||||
l = projecting <= 2.0
|
||||
self_test("projection_limits(3)", l.get_limits(self), [ 0, 2001 ])
|
||||
l = projecting == 2.0
|
||||
self_test("projection_limits(3)", l.get_limits(self), [ 2000, 2001 ])
|
||||
l = projecting > 2.0
|
||||
self_test("projection_limits(3)", l.get_limits(self), [ 2001, nil ])
|
||||
l = projecting >= 2.0
|
||||
self_test("projection_limits(3)", l.get_limits(self), [ 2000, nil ])
|
||||
l = 1.0 < projecting < 2.0
|
||||
self_test("projection_limits(3)", l.get_limits(self), [ 1001, 2000 ])
|
||||
|
||||
|
||||
l1.space(1.0, projection).polygons.output(100, 0)
|
||||
|
||||
l1.space(1.0, euclidian).polygons.output(110, 0)
|
||||
|
|
@ -23,7 +46,7 @@ l1.space(1.0, projection, only_opposite).output(113, 0)
|
|||
l1.space(1.0, projection, not_opposite).output(114, 0)
|
||||
|
||||
l1.isolated(1.0, euclidian).polygons.output(120, 0)
|
||||
l1.isolated(1.0, projection, projection_limits(0..2.0)).polygons.output(121, 0)
|
||||
l1.isolated(1.0, projection, projecting < 2.0.um).polygons.output(121, 0)
|
||||
l1.isolated(1.0, projection, whole_edges).polygons.output(122, 0)
|
||||
l1.isolated(1.0, projection, only_opposite).output(123, 0)
|
||||
l1.isolated(1.0, projection, not_opposite).output(124, 0)
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ l3.output(3, 0)
|
|||
ar = 4.0/3.0 # "L" shape
|
||||
l1.with_area_ratio(ar).output(100, 0)
|
||||
l1.without_area_ratio(ar).output(101, 0)
|
||||
l1.without_area_ratio(0..ar).output(102, 0)
|
||||
l1.with_area_ratio(ar+1e-6..).output(102, 0)
|
||||
l1.with_area_ratio(0.0, ar-1e-6).output(103, 0)
|
||||
|
||||
l1.squares.output(110, 0)
|
||||
|
|
@ -25,12 +25,12 @@ l1.non_squares.output(111, 0)
|
|||
|
||||
l2.with_bbox_aspect_ratio(2).output(120, 0)
|
||||
l2.with_bbox_aspect_ratio(1).output(121, 0)
|
||||
l2.with_bbox_aspect_ratio(0..1).output(122, 0)
|
||||
l2.with_bbox_aspect_ratio(..1).output(122, 0)
|
||||
l2.without_bbox_aspect_ratio(0..2).output(123, 0)
|
||||
|
||||
l2.with_relative_height(2).output(130, 0)
|
||||
l2.with_relative_height(1).output(131, 0)
|
||||
l2.with_relative_height(0..1).output(132, 0)
|
||||
l2.with_relative_height(..1).output(132, 0)
|
||||
l2.without_relative_height(0..2).output(133, 0)
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue