# Roxygen documentation generated programatically -------------------
#'
#'
#' Distance between two pairs of x-y coordinates. Input can be atomic ...
#'
#' @description
#'
#' Distance between two pairs of x-y coordinates. Input can be atomic or vector.
#'
#'
'xydist'
#' Distance between two x-y coordinates, but accepts each set of coord...
#'
#' @description
#'
#' Distance between two x-y coordinates, but accepts each set of coordinates as a vector of length 2,
#' with the first element the x coordinates, the second y.
#'
#'
'xydistvect'
#' Distance between two x-y coordinates.
#'
#' @description
#' Distance between two x-y coordinates. Accepts two sets of coordinates in a
#' single matrix.
#'
#' @section Arguments details:
#' `pts` A matrix with 4 columns ordered x1, y1, x2, y2.
#'
#' For use with apply.
#'
#' @template pts_matrix
#'
'xydistmat'
#' Distance from a point to a line (so its the perpendicular distance).
#'
#' @description
#' Distance from a point to a line (so it's the perpendicular distance).
#'
#' @details
#' Find distance from a pt (x then y coords) to a line segment given as start
#' and end points. Either x, y or end points can be vectors, but not both.
#'
#' It first finds perpendicular distance, then distance to each end point, and
#' returns the minimum.
#'
#' @section Arguments details:
#' If both `b, m` and `x, y` are vectors, they must all be same length.
#'
#' Note check for infinite slope, meaning that the intercept b is the
#' x-intercept.
#'
#' @template b_intercept
#' @template m_slope
#' @template x_coordinates
#' @template y_coordinates
#'
'perpendicular.distance'
#' Slope and intercept of the line perpendicular to another known line.
#'
#' @description
#' Finds the slope and intercept of the line perpendicular to a line whose slope
#' and intercept are given, through the points x,y.
#'
#' @section Arguments details:
#' Either `x` and `y` can be vectors, or `b` and `m` can be vectors, or if all
#' are vectors, must be same length.
#'
#' @template b_intercept
#' @template m_slope
#'
'perpendicular.line'
#' Slope and intercept of a line parallel to another known line.
#'
#' @description
#' Finds the slope and intercept of the line parallel to a line whose slope and
#' intercept are given, through the points `x, y`. Note that the intercept is
#' not needed. For any `m` that are infinite, the intercept is `x`.
#'
#' @template b_intercept
#' @template m_slope
#'
'parallel.line'
#' Finds the point where 2 lines intersect, given lines as 2 parameter...
#'
#' @description
#'
#' Finds the point where 2 lines intersect, given lines as 2 parameters each (intercept b then slope m).
#'
#' If the two lines are identical, it returns NAs. Note the check for both slopes being infinite (vertical lines).
#'
#' This is vectorized: either pair can be vector if other pair is atomic, or both can be same length vectors.
#'
#'
'intersection.of.lines'
#' Finds the points where a straight line, given lines as intercept b ...
#'
#' @description
#' Finds the points where a straight line, given lines as intercept b then slope
#' m, intersects with a curve defined by a sequence of segments.
#'
#' Intersections must be found for the line with every segment, then every one
#' checked with is.between.
#'
#' @section Arguments details:
#' - `b, m` Must be atomic.
#'
#' @template b_intercept
#' @template m_slope
#' @param curve Curve defined by a sequence of segments. Must be a dataframe
#' with columns x, y (or capital X, Y). having any number of segments.
#'
#' @return
#' The intersections are returned as a dataframe of x, y
#' coordinates.
#'
'intersection.line.curve'
#' Check whether a point x,y falls between two other points. The typic...
#'
#' @description
#'
#' Check whether a point x,y falls between two other points. The typical use is where the first point falls on the segment connecting the next two points.
#'
#' All arguments can be vector, but must be identical in length. An x falls between when it lies in [x1,x2).
#'
#'
'is.between'
#' Finds the point where 2 lines intersect, given each line as 2 pairs...
#'
#' @description
#'
#' Finds the point where 2 lines intersect, given each line as 2 pairs of points on the line
#'
#'
#' Both arguments must have columns x, y, with two rows, one row per point.
#'
#'
'line.intersection.pts'
#' Returns intercept and slope of a line given two pairs of coordinate...
#'
#' @description
#'
#' Returns intercept and slope of a line given two pairs of coordinates on the line. Arguments can be vectors; if both are vectors, must be same size.
#'
#' If the x's are exactly equal, so slope is infinite, it returns the x as the first argument.
#'
#'
'pts.to.interceptslope'
#' Draw a line segment between two points.
#'
#' @description
#' Draw a line segment between two points, where each point is a vector of x
#' then y coordinates.
#'
#' @template clr
#' @template lwidth
#'
'segmentPt'
#' Draw a rectangle given a matrix or dataframe of 4 x-y coordinates.
#'
#' @description
#' Draw a rectangle given a matrix or dataframe of 4 x-y coordinates. The
#' columns must have x first then y coordinates.
#'
#' @template add_plot
#' @template clr
#' @template lwidth
#'
'drawrectangle'
#' Given 3 sets of coordinates defining two line segments (middle poin...
#'
#' @description
#' Given 3 sets of coordinates defining two line segments (middle point is
#' intersection), find line bisecting the angle through middle point. This is
#' not vectorized. It only works with 3 sets of coordinates. Note that it is
#' necessary to correctly find the compass direction theta, which the slope
#' alone does not establish:
#' 1. If slope is negative and x2 >= x1 (travel is toward Quadrant IV), then
#' theta = atan(slope)
#' 2. If slope is negative with x2 < x1 (travel is toward Quadrant II), then
#' theta = atan(slope) + pi
#' 3. If slope is positive with x2 >= x1 (travel is toward Quadrant I), then
#' theta = atan(slope)
#' 4. If slope is positive with x2<x1 (travel is toward Quadrant III), then
#' theta = atan(slope) - pi
#'
#' This returns theta in (-pi, pi). Then the turn is calculated, ie the change in
#' direction between the two segments as the difference in theta, but it is
#' reset to be on (-pi, pi) as well in order to correctly estimate the mean
#' direction of travel (half the turn added to theta\[1]).
#'
'angleBisector'
#' Checks a vector of coordinates x, y to return which are inside a rectangle.
#'
#' @description
#' Checks a vector of coordinates x, y to return which are inside a rectangle.
#' For a much more general function for checking whether points are inside
#' polygons, use the function [splancs::inout()].
#'
'insideRectangle'
#' Check if points belong to quadrat.
#'
#' @description
#' Checks many points (dataframe pt with x and y) against a single quadrat whose
#' corners are given by as xlo, ylo, xhi, yhi.
#'
#' @details
#' This is same as [insideRectangle()], but accepting input as a matrix pts and a
#' single vector of the four corners of the rectange.
#'
#' @template pts_matrix
#'
#' @return
#' A logical vector; TRUE for the points inside.
#'
#' @seealso [insideRectangle()].
#'
'are.ptsinside'
#' Check a single pt (x and y) against a large number of quadrats whos...
#'
#' @description
#'
#' Check a single pt (x and y) against a large number of quadrats whose corners are given by the rows of coord, xlo, ylo, xhi, yhi.
#'
#' It returns the fraction of quadrats which the point falls inside. This is exactly like are.ptsinside() but allows there to be many
#' rectangles, defined by a dataframe coord.
#'
#'
'ispt.inside'
#' Determines whether any of the 4 corners of one rectangle are within...
#'
#' @description
#'
#' Determines whether any of the 4 corners of one rectangle are within a second rectangle. Both rectangles are submitted as c(x0,x1,y0,y1). If just one
#' of the corners is inside, it returns true. See insideRectange(), which has a similar name but does something different.
#'
'inside.rect'
#' Calculates points on a circle.
#'
#' @description
#' Calculates points on a circle.
#'
#' @inheritParams fullcircle
#'
'circle'
#' Create a dataframe for a full circle.
#'
#' @description
#' Create a dataframe for a full circle, with x values repeated to get top then
#' bottom. NA is inserted so this can be passed directly to graphing functions.
#'
#' @template x_coordinates
#' @param center x-y coordinates of the shape center (vector of 2)
#' @param radius Radius (scalar)
#'
'fullcircle'
#' Equation for (half) a canonical ellipse fullellipse Creates a data...
#'
#' @description
#' Equation for (half) a canonical
#'
#' @inheritParams fullcircle
#'
'ellipse'
#' Creates a dataframe for a full ellipse.
#'
#' @description
#' Creates a dataframe for a full ellipse.
#'
#' @inheritParams fullcircle
#'
'fullellipse'
#' Convert Cartesian coordinates to polar. Returns a dataframe of two ...
#'
#' @description
#'
#' Convert Cartesian coordinates to polar. Returns a dataframe of two columns named r and theta. This always
#' returns a theta between -pi/2 and pi/2. Note that polar.to.cartesian may not return the starting x, y submitted
#' to cartesian.to.polar due to problems with signs. It will work if theta is kept positive (ie, quadrant 1).
#'
#' @template x_coordinates
#' @param y input vector of y coordinates (same length as x)
#'
#' @examples
#' \dontrun{
#' cartesian.to.polar(2,4)}
#'
#'
'cartesian.to.polar'
#' Convert polar coordinates to Cartesian.
#'
#' @description
#' Convert polar coordinates to Cartesian.
#'
#' @return
#' A dataframe of two columns named x and y.
#'
#' @param r A vector of radii (distance from origin).
#' @param theta input vector of angle from horizontal (radians), same length as r
#'
#' @examples
#' \dontrun{
#' polar.to.cartesian(2, pi / 3)
#' }
#'
'polar.to.cartesian'
# Source code and original documentation ----------------------------
# <function>
# <name>
# xydist
# </name>
# <description>
# Distance between two pairs of x-y coordinates. Input can be atomic or vector.
# </description>
# <arguments>
#
# </arguments>
# <sample>
#
# </sample>
# <source>
#' @export
xydist=function(x1,y1,x2,y2)
return( sqrt( (x1-x2)^2 + (y1-y2)^2 ) )
# </source>
# </function>
#
#
#
# <function>
# <name>
# xydistvect
# </name>
# <description>
# Distance between two x-y coordinates, but accepts each set of coordinates as a vector of length 2,
# with the first element the x coordinates, the second y.
# </description>
# <arguments>
#
# </arguments>
# <sample>
#
# </sample>
# <source>
#' @export
xydistvect=function(pt1,pt2)
return( xydist(pt1[,1],pt1[,2],pt2[,1],pt2[,2]) )
# </source>
# </function>
#
#
#
# <function>
# <name>
# xydistmat
# </name>
# <description>
# Distance between two x-y coordinates, but accepts two sets of coordinates in a single matrix (4 columns ordered x1, y1, x2, y2).
# For use with apply.
# </description>
# <arguments>
#
# </arguments>
# <sample>
#
# </sample>
# <source>
#' @export
xydistmat=function(pts)
return( xydist(pts[,1],pts[,2],pts[,3],pts[,4]) )
# </source>
# </function>
#
#
#
# <function>
# <name>
# perpendicular.distance
# </name>
# <description>
# Distance from a point to a line (so it's the perpendicular distance);
# m and b are slope and intercept; x and y are coordinates. If both b,m and x,y are vectors, they must all be same length.
# Note check for infinite slope, meaning that the intercept b is the x-intercept.
# </description>
# <display>true</display>
# <update>true</update>
# <arguments>
# b: y-intercept
# m: line slope
# </arguments>
# <sample>
#
# </sample>
# <source>
#' @export
perpendicular.distance=function(b,m,x,y)
{
len=ifelse(length(b)>length(x),length(b),length(x))
minf=is.infinite(m)
result=rep(NA,len)
result=sqrt((y-m*x-b)^2/(1+m^2))
result[minf]=abs(x-b)[minf]
return(result)
}
# </source>
# </function>
#
# Find distance from a pt (x then y coords) to a line segment given as start and end points. Either x, y or end points can be vectors, but not both.
# It first finds perpendicular distance, then distance to each end point, and returns the minimum.
pt.to.segment=function(x,y,x1,y1,x2,y2)
{
bm=pts.to.interceptslope(pt1=data.frame(x1,y1),pt2=data.frame(x2,y2))
perpline=perpendicular.line(x=x,y=y,b=bm$b,m=bm$m)
intersect=intersection.of.lines(b1=bm$b,m1=bm$m,b2=perpline$b,m2=perpline$m)
perpcheck=is.between(intersect$x,intersect$y,x1,y1,x2,y2)
noperp=length(which(perpcheck))
perp=perpendicular.distance(x=x,y=y,b=bm$b,m=bm$m)
pt1dist=xydist(x,y,x1,y1)
pt2dist=xydist(x,y,x2,y2)
# browser()
# alldist=data.frame(pt1dist,pt2dist)
closest=c(min(pt1dist),min(pt2dist),min(pt1dist)+1)
perp[!perpcheck]=max(pt1dist)+1
if(noperp>0) closest[3]=min(perp)
choice=which.min(closest)
if(choice==1) { closeind=which.min(pt1dist); closex=x1[closeind]; closey=y1[closeind]; mindist=closest[1] }
else if(choice==2) { closeind=which.min(pt2dist); closex=x2[closeind]; closey=y2[closeind]; mindist=closest[2] }
else { closeind=which.min(perp); closex=intersect[closeind,'x']; closey=intersect[closeind,'y']; mindist=closest[3] }
return(c(x=closex,y=closey,index=closeind,distance=mindist))
# return(data.frame(mindist,perpcheck))
}
#
#
# <function>
# <name>
# perpendicular.line
# </name>
# <description>
# Finds the slope and intercept of the line perpendicular to a line whose slope and intercept are given,
# through the points x,y. Either x and y can be vectors, or b and m can be vectors, or if all are vectors, must be same length.
# </description>
# <arguments>
#
# </arguments>
# <sample>
#
# </sample>
# <source>
#' @export
perpendicular.line=function(b,m,x,y)
{
perpm=tan(pi/2+atan(m))
intercept=y-x*perpm
result=data.frame(b=intercept,m=perpm)
return(result)
}
# </source>
# </function>
#
#
#
# <function>
# <name>
# parallel.line
# </name>
# <description>
# Finds the slope and intercept of the line parallel to a line whose slope and intercept are given,
# through the points x,y. Note that the intercept is not needed. For any m that are infinite, the intercept is x.
# </description>
# <arguments>
#
# </arguments>
# <sample>
#
# </sample>
# <source>
#' @export
parallel.line=function(b,m,x,y)
{
minf=is.infinite(m)
len=IfElse(length(b)>length(x),length(b),length(x))
if(length(m)==1) slope=rep(m,len)
else slope=m
inter=y-m*x
inter[minf]=x
result=data.frame(b=inter,m=slope)
return(result)
}
# </source>
# </function>
#
#
#
# <function>
# <name>
# intersection.of.lines
# </name>
# <description>
# Finds the point where 2 lines intersect, given lines as 2 parameters each (intercept b then slope m).
# If the two lines are identical, it returns NAs. Note the check for both slopes being infinite (vertical lines).
# This is vectorized: either pair can be vector if other pair is atomic, or both can be same length vectors.
# </description>
# <arguments>
#
# </arguments>
# <sample>
#
# </sample>
# <source>
#' @export
intersection.of.lines=function(b1,m1,b2,m2)
{
len=IfElse(length(b2)>length(b1),length(b2),length(b1))
m1inf=(is.infinite(m1)&!is.infinite(m2))
m2inf=(is.infinite(m2)&!is.infinite(m1))
mfinite=(!m1inf&!m2inf)
exact=(m1==m2 & b1==b2) | (is.infinite(m1) & is.infinite(m2))
x=(b2-b1)/(m1-m2)
y=m1*x+b1
x[m1inf]=b1[m1inf]
y[m1inf]=(m2*b1+b2)[m1inf]
x[m2inf]=b2[m2inf]
y[m2inf]=(m1*b2+b1)[m2inf]
x[exact]=NA
y[exact]=NA
return(data.frame(x,y))
}
# </source>
# </function>
# <function>
# <name>
# intersection.line.curve
# </name>
# <description>
# Finds the points where a straight line, given lines as intercept b then slope m, intersects with a curve defined by a sequence of segments. Intersections must be found for the line with every segment, then every one checked with is.between. The intersections are returned as a dataframe of x, y coordinates. The b and m must be atomic. The curve must be a dataframe with columns x, y (or capital X, Y).
# having any number of segments.
# </description>
# <arguments>
#
# </arguments>
# <sample>
#
# </sample>
# <source>
#' @export
intersection.line.curve=function(b,m,curve)
{
cname=colnames(curve)
colnames(curve)[cname=='x']='X'
colnames(curve)[cname=='y']='Y'
nopt=dim(curve)[1]
segments=pts.to.interceptslope(pt1=curve[-nopt,c('X','Y')],pt2=curve[-1,c('X','Y')])
intersect=intersection.of.lines(b1=b,m1=m,b2=segments$b,m2=segments$m)
test=is.between(x=intersect$x,y=intersect$y,x1=curve$X[-nopt],y1=curve$Y[-nopt],x2=curve$X[-1],y2=curve$Y[-1])
return(intersect[test,])
}
#
#
# </source>
# </function>#
# <function>
# <name>
# is.between
# </name>
# <description>
# Check whether a point x,y falls between two other points. The typical use is where the first point falls on the segment connecting the next two points.
# All arguments can be vector, but must be identical in length. An x falls between when it lies in [x1,x2).
# </description>
# <arguments>
#
# </arguments>
# <sample>
#
# </sample>
# <source>
#' @export
is.between=function(x,y,x1,y1,x2,y2)
{
xout=ifelse(x2>x1,x<x1|x>=x2,x<=x2|x>x1)
yout=ifelse(y2>y1,y<y1|y>=y2,y<=y2|y>y1)
result=rep(TRUE,length(x))
result[xout|yout]=FALSE
# Arrangements where end points have precisely matching coordinates.
exactX=(x1==x2)
result[exactX & x==x1 & y1<y2 & y>=y1 & y<y2]=TRUE
result[exactX & x==x1 & y1>y2 & y>=y2 & y<y1]=TRUE
exactY=(y1==y2)
result[exactY & y==y1 & x1<x2 & x>=x1 & x<x2]=TRUE
result[exactY & y==y1 & x1>x2 & x>=x2 & x<x1]=TRUE
return(result)
}
# </source>
# </function>
#
#
# <function>
# <name>
# line.intersection.pts
# </name>
# <description>
# Finds the point where 2 lines intersect, given each line as 2 pairs of points on the line
# </description>
# <arguments>
# Both arguments must have columns x, y, with two rows, one row per point.
# </arguments>
# <sample>
#
# </sample>
# <source>
#' @export
line.intersection.pts=function(pts1,pts2)
{
line1=pts.to.interceptslope(pts1[1,],pts1[2,])
line2=pts.to.interceptslope(pts2[1,],pts2[2,])
return(line.intersection(m1=line1[1],b1=line1[2],m2=line2[1],b2=line2[2]))
}
# </source>
# </function>
#
#
#
# <function>
# <name>
# pts.to.interceptslope
# </name>
# <description>
# Returns intercept and slope of a line given two pairs of coordinates on the line. Arguments can be vectors; if both are vectors, must be same size.
# If the x's are exactly equal, so slope is infinite, it returns the x as the first argument.
# </description>
# <arguments>
#
# </arguments>
# <sample>
#
# </sample>
# <source>
#' @export
pts.to.interceptslope=function(pt1,pt2)
{
if(is.null(dim(pt1))) { x1=pt1[1]; y1=pt1[2] }
else { x1=pt1[,1]; y1=pt1[,2] }
if(is.null(dim(pt2))) { x2=pt2[1]; y2=pt2[2] }
else { x2=pt2[,1]; y2=pt2[,2] }
len=IfElse(length(x2)>length(x1),length(x2),length(x1))
exact=(x1==x2)
slope=(y2-y1)/(x2-x1)
inter=y1-slope*x1
slope[exact]=Inf
inter[exact]=x1[exact]
result=data.frame(b=inter,m=slope)
}
# </source>
# </function>
#
#
# <function>
# <name>
# segmentPt
# </name>
# <description>
# Draw a line segment between two points, where each point is a vector of x then y coordinates
# </description>
# <arguments>
#
# </arguments>
# <sample>
#
# </sample>
# <source>
#' @export
segmentPt=function(pt1,pt2,clr='black',lwidth=1)
{
if(is.null(dim(pt1))) { x1=pt1[1]; y1=pt1[2] }
else { x1=pt1[,1]; y1=pt1[,2] }
if(is.null(dim(pt2))) { x2=pt2[1]; y2=pt2[2] }
else { x2=pt2[,1]; y2=pt2[,2] }
segments(x0=x1,x1=x2,y0=y1,y1=y2,col=clr,lwd=lwidth)
}
# </source>
# </function>
#
#
#
# <function>
# <name>
# drawrectangle
# </name>
# <description>
# Draw a rectangle given a matrix or dataframe of 4 x-y coordinates. The columns must have x first then y coordinates.
# </description>
# <arguments>
#
# </arguments>
# <sample>
#
# </sample>
# <source>
#' @export
drawrectangle=function(corners,add=TRUE,clr='black',lwidth=1)
{
if(!add)
{
xrange=range(corners$x)
yrange=range(corners$y)
plot(xrange[1],yrange[1],xlim=xrange,ylim=yrange,xlab="",ylab="",col="white",axes=FALSE)
}
segmentPt(corners[1,],corners[2,],clr=clr,lwidth=lwidth)
segmentPt(corners[2,],corners[3,],clr=clr,lwidth=lwidth)
segmentPt(corners[3,],corners[4,],clr=clr,lwidth=lwidth)
segmentPt(corners[1,],corners[4,],clr=clr,lwidth=lwidth)
}
# </source>
# </function>
#
#
#
# <function>
# <name>
# angleBisector
# </name>
# <description>
# Given 3 sets of coordinates defining two line segments (middle point is intersection), find line bisecting the angle through middle point. This is not vectorized. It only works with 3 sets of coordinates. Note that it is necessary to correctly find the compass direction theta, which the slope alone does not establish:
# 1) If slope is negative and x2>=x1 (travel is toward Quadrant IV), then theta=atan(slope)
# 2) If slope is negative with x2<x1 (travel is toward Quadrant II), then theta=atan(slope)+pi
# 3) If slope is positive with x2>=x1 (travel is toward Quadrant I), then theta=atan(slope)
# 4) If slope is positive with x2<x1 (travel is toward Quadrant III), then theta=atan(slope)-pi
# This returns theta in (-pi,pi). Then the turn is calculated, ie the change in direction between the two segments as the difference in theta, but it is reset to be on (-pi,pi) as well in order to correctly estimate the mean direction of travel (half the turn added to theta[1]).
# </description>
# <arguments>
#
# </arguments>
# <sample>
#
# </sample>
# <source>
#' @export
angleBisector=function(corners)
{
bm=pts.to.interceptslope(pt1=corners[1:2,],pt2=corners[2:3,])
left=(corners[1:2,1]>=corners[2:3,1])
right=!left
up=(bm[,2]>=0 & right) | (bm[,2]<0 & left)
down=!up
QI=right&up
QII=left&up
QIII=left&down
QIV=right&down
theta=atan(bm[,2])
theta[QII]=atan(bm[QII,2])+pi
theta[QIII]=atan(bm[QIII,2])-pi
fullturn=theta[2]-theta[1]
if(fullturn>pi) turn=fullturn-2*pi
else if(-fullturn>pi) turn=fullturn+2*pi
else turn=fullturn
slope=theta[1]+turn/2
# slope=mean(theta)
perpm=tan(pi/2+slope)
result=parallel.line(b=NA,m=perpm,x=corners[2,1],y=corners[2,2])
# avgtravel=parallel.line(b=NA,m=tan(slope),x=corners[2,1],y=corners[2,2])
# if(length(which(QIII))>0 & length(which(QII))>0) browser()
return(drp(as.matrix(result)))
}
# </source>
# </function>
# <function>
# <name>
# insideRectangle
# </name>
# <description>
# Checks a vector of coordinates x, y to return which are inside a rectangle. For a much more general function for checking whether
# points are inside polygons, use the function inout() in the package splancs.
# </description>
# <arguments>
#
# </arguments>
# <sample>
#
# </sample>
# <source>
#' @export
insideRectangle=function(x,y,xrange,yrange)
{
inX=x>=xrange[1] & x<xrange[2] & !is.na(x)
inY=y>=yrange[1] & y<yrange[2] & !is.na(y)
return(inX&inY)
}
# </source>
# </function>
#
# <function>
# <name>
## are.ptsinside
# </name>
# <description>
# Checks many points (dataframe pt with x and y) against a single quadrat whose corners are given by as xlo, ylo, xhi, yhi.
# It returns a logical vector, TRUE for the points inside. This is same as insideRectange, but accepting input as a matrix pts
# and a single vector of the four corners of the rectange.
# </description>
# <arguments>
#
# </arguments>
# <sample>
#
# </sample>
# <source>
#' @export
are.ptsinside=function(pts,coord)
{
return(insideRectange(x=pts[,1],y=pts[,2],xrange=coord[,c(1,3)],yrange=coord[,c(2,4)]))
}
# </source>
# </function>
# <function>
# <name>
# ispt.inside
# </name>
# <description>
# Check a single pt (x and y) against a large number of quadrats whose corners are given by the rows of coord, xlo, ylo, xhi, yhi.
# It returns the fraction of quadrats which the point falls inside. This is exactly like are.ptsinside() but allows there to be many
# rectangles, defined by a dataframe coord.
# </description>
# <arguments>
#
# </arguments>
# <sample>
#
# </sample>
# <source>
#' @export
ispt.inside=function(pt,coord)
{
norect=dim(coord)[1]
inside=logical()
for(i in 1:norect) logical[i]=are.ptsinside(pt,drp(coord[i,]))
return(inside)
}
# </source>
# </function>
#
# <function>
# <name>
# inside.rect
# </name>
# <description>
# Determines whether any of the 4 corners of one rectangle are within a second rectangle. Both rectangles are submitted as c(x0,x1,y0,y1). If just one
# of the corners is inside, it returns true. See insideRectange(), which has a similar name but does something different.
# </description>
# <arguments>
#
# </arguments>
# <sample>
#
# </sample>
# <source>
#' @export
inside.rect=function(rect1,rect2)
{
if(rect1[2]<rect2[1]) return(FALSE)
if(rect1[1]>rect2[2]) return(FALSE)
if(rect1[4]<rect2[3]) return(FALSE)
if(rect1[3]>rect2[4]) return(FALSE)
return(TRUE)
}
# </source>
# </function>
#
#
# <function>
# <name>
# circle
# </name>
# <description>
# Calculates points on a
# </description>
# <arguments>
#
# </arguments>
# <sample>
#
# </sample>
# <source>
#' @export
circle=function(x,center=c(0,0),radius=5,half="top")
{
xprime=x-center[1]
yprimesq=radius^2-xprime^2
yprime=numeric()
yprime[yprimesq>=0]=sqrt(yprimesq[yprimesq>=0])
if(half=="bottom") yprime=(-1)*yprime
y=yprime+center[2]
return(y)
}
# </source>
# </function>
#
#
#
# <function>
# <name>
# fullcircle
# </name>
# <description>
# Create a dataframe for a full circle, with x values repeated to get top then bottom. NA is inserted
# so this can be passed directly to graphing functions.
# </description>
# <arguments>
#
# </arguments>
# <sample>
#
# </sample>
# <source>
#' @export
fullcircle=function(x,center=c(0,0),radius=5)
{
tophalf=circle(x,center,radius,half='top')
bottomhalf=circle(x,center,radius,half='bottom')
len=length(x)
result=data.frame(x=c(x,NA,x[len:1]),y=c(tophalf,NA,bottomhalf[len:1]))
return(result)
}
# </source>
# </function>
#
#
#
# <function>
# <name>
# ellipse
# </name>
# <description>
# Equation for (half) a canonical
# </description>
# <arguments>
#
# </arguments>
# <sample>
#
# </sample>
# <source>
#' @export
ellipse=function(x,center=c(0,0),radius=c(7,5),half='top')
{
xprime=x-center[1]
inc=abs(xprime)<=radius[1]
yprimesq=yprime=t=numeric()
t[inc]=acos(xprime[inc]/radius[1])
yprime[inc]=radius[2]*sin(t[inc])
if(half=="bottom") yprime=(-1)*yprime
y=yprime+center[2]
return(y)
}
# </source>
# </function>
#
#
#
# <function>
# <name>
# fullellipse
# </name>
# <description>
# Creates a dataframe for a full ellipse.
# </description>
# <arguments>
# <ul>
# <li> x = input x coordinates
# <li> center = x-y coordinates of ellipse center (vector of 2)
# </ul>
# </arguments>
# <sample>
#
# </sample>
# <source>
#' @export
fullellipse=function(x,center=c(0,0),radius=c(7,5))
{
tophalf=ellipse(x,center,radius,half='top')
bottomhalf=ellipse(x,center,radius,half='bottom')
result=data.frame(x=c(x,NA,x),y=c(tophalf,NA,bottomhalf))
return(result)
}
# </source>
# </function>
#
#
# <function>
# <name>
# cartesian.to.polar
# </name>
# <description>
# Convert Cartesian coordinates to polar. Returns a dataframe of two columns named r and theta. This always
# returns a theta between -pi/2 and pi/2. Note that polar.to.cartesian may not return the starting x, y submitted
# to cartesian.to.polar due to problems with signs. It will work if theta is kept positive (ie, quadrant 1).
# </description>
# <arguments>
# <ul>
# <li> x = input vector of x coordinates
# <li> y = input vector of y coordinates (same length as x)
# </ul>
# </arguments>
# <sample>
# cartesian.to.polar(2,4)
# </sample>
# <source>
#' @export
cartesian.to.polar=function(x,y)
{
r=sqrt(x^2+y^2)
theta=atan(y/x)
zeroes=(x==0)
theta[zeroes&y>0]=pi/2
theta[zeroes&y<0]=(-1)*pi/2
return(data.frame(r,theta))
}
# </source>
# </function>
#
# <function>
# <name>
# polar.to.cartesian
# </name>
# <description>
# Convert polar coordinates to Cartesian. Returns a dataframe of two columns named x and y.
# </description>
# <arguments>
# <ul>
# <li> r = input vector of radii (distance from origin)
# <li> theta = input vector of angle from horizontal (radians), same length as r
# </ul>
# </arguments>
# <sample>
# polar.to.cartesian(2,pi/3)
# </sample>
# <source>
#' @export
polar.to.cartesian=function(r,theta)
{
x=r*cos(theta)
y=r*sin(theta)
return(data.frame(x,y))
}
# </source>
# </function>
### Should be deleted ...
#
# <function>
# <name>
# slope.intercept.frompts
# </name>
# <description>
# This is an old version of pts.to.interceptslope, returns slope than intercept of a line given two points. The alternate function, pts.to.interceptslope,
# returns intercept then slope, which is more standard. This is kept for compatibility with old functions.
# </description>
# <arguments>
#
# </arguments>
# <sample>
#
# </sample>
# <source>
#' @export
#slope.intercept.frompts=function(pt1,pt2)
#{
# line=pts.to.interceptslope(pt1,pt2)
# return(c(line[2:1]))
#}
# </source>
# </function>
#
#
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.