bilat {biogeom} | R Documentation |
Measure of the Extent of Bilateral Symmetry of A Polygon
Description
bilat
is used to measure the extent of bilateral (a)symmetry and other measures for a polygon (e.g., a leaf).
Usage
bilat(x, y, strip.num = 200, peri.np = NULL, n.loop = 60,
auto.search = TRUE, animation.fig = TRUE, time.interval = 0.001,
unit = "cm", main = NULL, diff.fig = TRUE, angle = NULL,
ratiox = 0.02, ratioy = 0.08, fd.opt = TRUE, frac.fig = TRUE,
denomi.range = seq(8, 30, by = 1))
Arguments
x |
the |
y |
the |
strip.num |
the number of equidistant strips intersecting with the polygon that are horizontally placed. See Shi et al. (2018, 2020) for details. |
peri.np |
the number of data points on the boundary retained for calculating the perimeter of the polygon. |
n.loop |
the number of data points to randomly sample for calculating the mean perimeter of the polygon. |
auto.search |
an optional argument to automatically search the maximum distance between two points on the polygon's boundary. |
animation.fig |
the option of showing the data points on the polygon's boundary in an animation. |
time.interval |
the time interval at which to suspend execution, in seconds. |
unit |
the units of the |
main |
the main title of the figure. |
diff.fig |
an optional argument to draw the differences in areas between the intersections of the strips
with the upper part of the polygon and the intersections of the strips with the lower part of the polygon.
The polygon is divided into the upper and lower parts by the |
angle |
the angle between the major axis (i.e., the leaf length axis) and the |
fd.opt |
An optional argument to use the box-counting method to calculate the fractal dimension of the polygon's boundary on a log-log scale. |
ratiox |
the |
ratioy |
the |
frac.fig |
an optional argument to draw the results of the linear fitting using the box-counting method to calculate the fractal dimension of the polygon's boundary on a log-log scale. |
denomi.range |
the number of equidistant segments of the maximum range
between the range of the |
Details
The data of x
and y
should be the coordinates adjusted using the adjdata
function.
If peri.np = NULL
, the number of length(x)
is used to calculate the perimeter of the polygon;
if peri.np
is a positive integer, the number of data points retained on the polygon's boundary
is equal to peri.np
and random sampling for retaining peri.np
data points is carried out
n.loop
times for calculating the mean perimeter of the polygon. That is to say, the final output for
the perimeter is the mean of the n.loop
perimeters (i.e., replicates). If the user wants to get a consistent result
for the mean perimeter, the set.seed
function can be used. In addition, if length(x) < peri.np
,
peri.np
then becomes length(x)
rather than the specified value in Arguments.
If the polygon apparently has a major axis (e.g., the leaf length axis for an ovate leaf), auto.search
is appropriate. If the major axis of the polygon is not the straight line through two points on the polygon's
boundary having the maximum distance, the user can define the major axis using the locator
function in graphic by clicking two points on or near the polygon's boundary. The location of the first click
should be northeast of the location of the second click. This means that the angle between the straight line
through the locations of the two clicks and the x
-axis should range from 0 to \pi
/2. The locations of the
clicks can be on the boundary or be approximate to the boundary. The function will automatically find the nearest
data point on the boundary to the location of each click.
When angle = NULL
, the observed polygon will be shown at its initial angle in the scanned image;
when angle
is a numerical value (e.g., \pi/4
) defined by the user, it indicates that the major axis
is rotated \pi/4
counterclockwise from the x
-axis.
Value
x |
the |
y |
the |
phi |
the angle between the length axis (i.e., the major axis) of the polygon and the |
n1 |
the number of data points on the upper boundary of the polygon. |
n2 |
the number of data points on the lower boundary of the polygon. |
n |
the number of data points on the whole polygon's boundary. |
total.poly |
an object of class "ppp" representing a point pattern dataset in the two-dimensional plane, representing the polygon's boundary. |
upper.poly |
an object of class "ppp" representing a point pattern dataset
in the two-dimensional plane, representing the upper boundary of the polygon along the |
lower.poly |
an object of class "ppp" representing a point pattern dataset
in the two-dimensional plane, representing the lower boundary of the polygon along the |
D |
the differences in areas between the upper and lower boundaries of the polygon. |
par.upper.area |
the area of the upper boundary of the polygon along the |
par.lower.area |
the area of the lower boundary of the polygon along the |
SI |
the standardized index for bilateral (a)symmetry for the polygon. |
AR |
the ratio of the areas of the upper to the lower parts of the polygon. |
scan.length |
the length of the polygon. The default is the maximum distance between two points on the polygon's boundary. |
scan.width |
the maximum width of the polygon. |
scan.area |
the area of the polygon. |
scan.perimeter |
the perimeter of the polygon
based on all data points or a mean of |
x.width |
distance from the base to a point on the major axis associated with the maximum width of the polygon. |
width.1e |
the width associated with 1/8 of |
width.2e |
the width associated with 2/8 of |
width.4e |
the width associated with 4/8 of |
width.6e |
the width associated with 6/8 of |
width.7e |
the width associated with 7/8 of |
bi.test |
the testing results for |
a |
the estimate of the intercept obtained using the box-counting method to calculate the fractal dimension of the polygon's boundary. |
sd.a |
the standard deviation of the estimated intercept. |
lci.a |
the lower bound of the 95% confidence interval of the estimated intercept. |
uci.a |
the upper bound of the 95% confidence interval of the estimated intercept. |
b |
the estimate of the slope obtained using the box-counting method to calculate the fractal dimension of the polygon's boundary. |
sd.b |
the standard deviation of the estimated slope. |
lci.a |
the lower bound of the 95% confidence interval of the estimated slope. |
uci.a |
the upper bound of the 95% confidence interval of the estimated slope. |
r.sq |
the coefficient of determination obtained when using the box-counting method to calculate the fractal dimension of the polygon's boundary. |
delta |
the vector of box sizes used in the box-counting method to calculate the fractal dimension of the polygon's boundary. |
N |
the number of boxes that include at least one pixel of the polygon's boundary. |
Note
The polygon is expected to have an apparent major axis (e.g., the straight line through two points
on the polygon's boundary having the maximum distance or one that can be clearly defined to pass by
two landmarks on the polygon's boundary [i.e., the leaf length axis, the egg length axis, etc.]).
The polygon is placed with its major axis overlapping the x
-axis; the base of the polygon is
located at the origin; the apex of the polygon is located to the right of the base.
phi
is equal to angle
when angle
is not null.
In theory, n1 + n2 = n
, but in most cases n1 + n2
is slightly smaller than n
.
The reason is that very few boundary points fall outside the the lower and upper boundaries of the polygon
when using the intersect.owin
function in spatstat.geom. However, this does not considerably affect the results.
The log-transformed SI
and
the log-transformed AR
are demontrated to have a more symmetrical frequency distribution than their original forms.
This is important when performing an analysis of variance between (or among) groups to compared
their extents of bilateral (a)symmetry. See Shi et al. (2020) for details.
The box-counting approach uses a group of boxes (squares for simplicity) with different
sizes (\delta
) to divide the leaf vein image into different parts. Let N
represent the number
of boxes that include at least one pixel of the polygon's boundary.
The maximum of the range of the x
coordinates and the range of the y
coordinates
for the pixels of the polygon's boundary is defined as z
. Let \delta
represent the vector of
z
/denomi.range
. We then used the following equation to calculate the fractal
dimension of the polygon's boundary:
\mathrm{ln } N = a + b\, \mathrm{ln} \left(\delta^{-1}\right),
where b
is the theoretical value of the fractal dimension. We can use its estimate as the
numerical value of the fractal dimension for the polygon's boundary.
Author(s)
Peijian Shi pjshi@njfu.edu.cn, Johan Gielis johan.gielis@uantwerpen.be, Brady K. Quinn Brady.Quinn@dfo-mpo.gc.ca.
References
Shi, P., Gielis, J., Quinn, B.K., Niklas, K.J., Ratkowsky, D.A., Schrader, J., Ruan, H.,
Wang, L., Niinemets, Ü. (2022) 'biogeom': An R package for simulating and fitting natural
shapes. Annals of the New York Academy of Sciences 1516, 123-
134. doi:10.1111/nyas.14862
Shi, P., Niinemets, Ü., Hui, C., Niklas, K.J., Yu, X., Hölscher, D. (2020) Leaf bilateral symmetry and the scaling of the perimeter vs. the surface area in 15 vine species. Forests 11, 246. doi:10.3390/f11020246
Shi, P., Zheng, X., Ratkowsky, D.A., Li, Y., Wang, P., Cheng, L. (2018) A simple method for measuring the bilateral symmetry of leaves. Symmetry 10, 118. doi:10.3390/sym10040118
See Also
Examples
data(bambooleaves)
uni.C <- sort( unique(bambooleaves$Code) )
ind <- 3
Data <- bambooleaves[bambooleaves$Code==uni.C[ind], ]
x0 <- Data$x
y0 <- Data$y
dev.new()
plot( x0, y0, asp=1, type="l", cex.lab=1.5, cex.axis=1.5,
xlab=expression(italic(x)), ylab=expression(italic(y)) )
Res1 <- adjdata(x0, y0, ub.np=2000, len.pro=1/20)
x1 <- Res1$x
y1 <- Res1$y
Res2 <- bilat( x=x1, y=y1, time.interval=0.00045,
peri.np=NULL, auto.search=TRUE,
fd.opt=TRUE )
Res2$scan.perimeter
set.seed(123)
Res3 <- bilat( x=x1, y=y1, time.interval=0.00045,
peri.np=500, n.loop=30,
auto.search=TRUE, fd.opt=FALSE )
Res3$scan.perimeter
set.seed(123)
Res4 <- bilat( x=x1, y=y1, time.interval=0.00045,
peri.np=500, n.loop=30,
auto.search=TRUE, fd.opt=FALSE, angle=pi/4 )
Res4$scan.perimeter
set.seed(123)
Res5 <- bilat( x=x1, y=y1, time.interval=0.00045,
peri.np=500, n.loop=30,
auto.search=TRUE, fd.opt=FALSE, angle=0 )
Res5$scan.perimeter
if(interactive()){
# The angle between the leaf length axis (namely the straight
# line through the leaf apex and base) and the horizontal axis
# should be between 0 and pi/2 for a scanned leaf's profile.
# Here, the user needs to first click the leaf apex,
# and then click the leaf base.
set.seed(123)
Res6 <- bilat( x=x1, y=y1, time.interval=0.00045,
peri.np=500, n.loop=30,
auto.search=FALSE, fd.opt=FALSE, angle=NULL )
Res6$scan.perimeter
}
set.seed(NULL)
graphics.off()