Segment¶
Under Construction
This documentation is auto-generated, and is a work in progress. Please see the source code at https://github.com/phetsims/kite/blob/main/js/segments/Segment.ts for the most up-to-date information.
Overview¶
A segment represents a specific curve with a start and end.
Each segment is treated parametrically, where t=0 is the start of the segment, and t=1 is the end. Values of t between those represent points along the segment.
@author Jonathan Olson <jonathan.olson@colorado.edu> /* global paper */
Class Segment¶
Constructor¶
new Segment()¶
Instance Methods¶
positionAt( t : number ) : Vector2¶
Returns the position parametrically, with 0 <= t <= 1. NOTE that this function doesn't keep a constant magnitude tangent.
tangentAt( t : number ) : Vector2¶
Returns the non-normalized tangent (dx/dt, dy/dt) of this segment at the parametric value of t, with 0 <= t <= 1.
curvatureAt( t : number ) : number¶
Returns the signed curvature (positive for visual clockwise - mathematical counterclockwise)
subdivided( t : number ) : Segment[]¶
Returns an array with up to 2 sub-segments, split at the parametric t value. The segments together should make the same shape as the original segment.
getSVGPathFragment() : string¶
Returns a string containing the SVG path. assumes that the start point is already provided, so anything that calls this needs to put the M calls first
strokeLeft( lineWidth : number ) : Segment[]¶
Returns an array of segments that will draw an offset curve on the logical left side
strokeRight( lineWidth : number ) : Segment[]¶
Returns an array of segments that will draw an offset curve on the logical right side
windingIntersection( ray : Ray2 ) : number¶
Returns the winding number for intersection with a ray
getInteriorExtremaTs() : number[]¶
Returns a list of t values where dx/dt or dy/dt is 0 where 0 < t < 1. subdividing on these will result in monotonic segments
intersection( ray : Ray2 ) : RayIntersection[]¶
Returns a list of intersections between the segment and the ray.
getBounds() : Bounds2¶
Returns a {Bounds2} representing the bounding box for the segment.
getSignedAreaFragment() : number¶
Returns signed area contribution for this segment using Green's Theorem
getNondegenerateSegments() : Segment[]¶
Returns a list of non-degenerate segments that are equivalent to this segment. Generally gets rid (or simplifies) invalid or repeated segments.
getOverlaps( segment : Segment, epsilon? : number ) : Overlap[] | null¶
writeToContext( context : CanvasRenderingContext2D )¶
Draws the segment to the 2D Canvas context, assuming the context's current location is already at the start point
transformed( matrix : Matrix3 ) : Segment¶
Returns a new segment that represents this segment after transformation by the matrix
reversed() : Segment¶
invalidate()¶
serialize() : SerializedSegment¶
areStrokedBoundsDilated() : boolean¶
Will return true if the start/end tangents are purely vertical or horizontal. If all of the segments of a shape have this property, then the only line joins will be a multiple of pi/2 (90 degrees), and so all of the types of line joins will have the same bounds. This means that the stroked bounds will just be a pure dilation of the regular bounds, by lineWidth / 2.
getBoundsWithTransform( matrix : Matrix3 ) : Bounds2¶
TODO: override everywhere so this isn't necessary (it's not particularly efficient!) https://github.com/phetsims/kite/issues/76
slice( t0 : number, t1 : number ) : Segment¶
Extracts a slice of a segment, based on the parametric value.
Given that this segment is represented by the interval [0,1]
subdivisions( tList : number[] ) : Segment[]¶
@param tList - list of sorted t values from 0 <= t <= 1
subdividedIntoMonotone() : Segment[]¶
Return an array of segments from breaking this segment into monotone pieces
isSufficientlyFlat( distanceEpsilon : number, curveEpsilon : number ) : boolean¶
Determines if the segment is sufficiently flat (given certain epsilon values)
@param distanceEpsilon - controls level of subdivision by attempting to ensure a maximum (squared) deviation from the curve @param curveEpsilon - controls level of subdivision by attempting to ensure a maximum curvature change between segments
getArcLength( distanceEpsilon? : number, curveEpsilon? : number, maxLevels? : number ) : number¶
Returns the (sometimes approximate) arc length of the segment.
getDashValues( lineDash : number[], lineDashOffset : number, distanceEpsilon : number, curveEpsilon : number ) : DashValues¶
Returns information about the line dash parametric offsets for a given segment.
As always, this is fairly approximate depending on the type of segment.
@param lineDash @param lineDashOffset @param distanceEpsilon - controls level of subdivision by attempting to ensure a maximum (squared) deviation from the curve @param curveEpsilon - controls level of subdivision by attempting to ensure a maximum curvature change between segments
toPiecewiseLinearSegments( options : PiecewiseLinearOptions, minLevels? : number, maxLevels? : number, segments? : Line[], start? : Vector2, end? : Vector2 ) : Line[]¶
@param [options] @param [minLevels] - how many levels to force subdivisions @param [maxLevels] - prevent subdivision past this level @param [segments] @param [start] @param [end]
toPiecewiseLinearOrArcSegments( providedOptions : PiecewiseLinearOrArcOptions ) : Segment[]¶
Returns a list of Line and/or Arc segments that approximates this segment.
getClosestPoints( point : Vector2 ) : ClosestToPointResult[]¶
Instance Properties¶
invalidationEmitter : TEmitter¶
Static Methods¶
closestToPoint( segments : Segment[], point : Vector2, threshold : number ) : ClosestToPointResult[]¶
List of results (since there can be duplicates), threshold is used for subdivision, where it will exit if all of the segments are shorter than the threshold
TODO: solve segments to determine this analytically! https://github.com/phetsims/kite/issues/76
polynomialGetOverlapCubic( p0s : number, p1s : number, p2s : number, p3s : number, q0s : number, q1s : number, q2s : number, q3s : number ) : PossibleSimpleOverlap¶
Given the cubic-premultiplied values for two cubic bezier curves, determines (if available) a specified (a,b) pair such that p( t ) === q( a * t + b ).
Given a 1-dimensional cubic bezier determined by the control points p0, p1, p2 and p3, compute:
[ p0s ] [ 1 0 0 0 ] [ p0 ] [ p1s ] == [ -3 3 0 0 ] * [ p1 ] [ p2s ] == [ 3 -6 3 0 ] * [ p2 ] [ p3s ] [ -1 3 -3 1 ] [ p3 ]
see Cubic.getOverlaps for more information.
polynomialGetOverlapQuadratic( p0s : number, p1s : number, p2s : number, q0s : number, q1s : number, q2s : number ) : PossibleSimpleOverlap¶
Given the quadratic-premultiplied values for two quadratic bezier curves, determines (if available) a specified (a,b) pair such that p( t ) === q( a * t + b ).
Given a 1-dimensional quadratic bezier determined by the control points p0, p1, p2, compute:
[ p0s ] [ 1 0 0 ] [ p0 ] [ p1s ] == [ -2 2 0 ] * [ p1 ] [ p2s ] [ 2 -2 3 ] * [ p2 ]
see Quadratic.getOverlaps for more information.
polynomialGetOverlapLinear( p0s : number, p1s : number, q0s : number, q1s : number ) : PossibleSimpleOverlap¶
Given the linear-premultiplied values for two lines, determines (if available) a specified (a,b) pair such that p( t ) === q( a * t + b ).
Given a line determined by the control points p0, p1, compute:
[ p0s ] == [ 1 0 ] * [ p0 ] [ p1s ] == [ -1 1 ] * [ p1 ]
see Quadratic/Cubic.getOverlaps for more information.
intersect( a : Segment, b : Segment ) : SegmentIntersection[]¶
Returns all the distinct (non-endpoint, non-finite) intersections between the two segments.
deserialize( obj : SerializedSegment ) : Segment¶
Returns a Segment from the serialized representation.
isSufficientlyFlat( distanceEpsilon : number, curveEpsilon : number, start : Vector2, middle : Vector2, end : Vector2 ) : boolean¶
Determines if the start/middle/end points are representative of a sufficiently flat segment (given certain epsilon values)
@param start @param middle @param end @param distanceEpsilon - controls level of subdivision by attempting to ensure a maximum (squared) deviation from the curve @param curveEpsilon - controls level of subdivision by attempting to ensure a maximum curvature change between segments
filterClosestToPointResult( results : ClosestToPointResult[] ) : ClosestToPointResult[]¶
Class Arc¶
A circular arc (a continuous sub-part of a circle).
@author Jonathan Olson <jonathan.olson@colorado.edu>
Constructor¶
new Arc( center : Vector2, radius : number, startAngle : number, endAngle : number, anticlockwise : boolean )¶
Instance Methods¶
setCenter( center : Vector2 ) : this¶
Sets the center of the Arc.
getCenter() : Vector2¶
Returns the center of this Arc.
setRadius( radius : number ) : this¶
Sets the radius of the Arc.
getRadius() : number¶
Returns the radius of this Arc.
setStartAngle( startAngle : number ) : this¶
Sets the startAngle of the Arc.
getStartAngle() : number¶
Returns the startAngle of this Arc.
setEndAngle( endAngle : number ) : this¶
Sets the endAngle of the Arc.
getEndAngle() : number¶
Returns the endAngle of this Arc.
setAnticlockwise( anticlockwise : boolean ) : this¶
Sets the anticlockwise of the Arc.
getAnticlockwise() : boolean¶
Returns the anticlockwise of this Arc.
positionAt( t : number ) : Vector2¶
Returns the position parametrically, with 0 <= t <= 1.
NOTE: positionAt( 0 ) will return the start of the segment, and positionAt( 1 ) will return the end of the segment.
This method is part of the Segment API. See Segment.js's constructor for more API documentation.
tangentAt( t : number ) : Vector2¶
Returns the non-normalized tangent (dx/dt, dy/dt) of this segment at the parametric value of t, with 0 <= t <= 1.
NOTE: tangentAt( 0 ) will return the tangent at the start of the segment, and tangentAt( 1 ) will return the tangent at the end of the segment.
This method is part of the Segment API. See Segment.js's constructor for more API documentation.
curvatureAt( t : number ) : number¶
Returns the signed curvature of the segment at the parametric value t, where 0 <= t <= 1.
The curvature will be positive for visual clockwise / mathematical counterclockwise curves, negative for opposite curvature, and 0 for no curvature.
NOTE: curvatureAt( 0 ) will return the curvature at the start of the segment, and curvatureAt( 1 ) will return the curvature at the end of the segment.
This method is part of the Segment API. See Segment.js's constructor for more API documentation.
subdivided( t : number ) : Arc[]¶
Returns an array with up to 2 sub-segments, split at the parametric t value. Together (in order) they should make up the same shape as the current segment.
This method is part of the Segment API. See Segment.js's constructor for more API documentation.
invalidate()¶
Clears cached information, should be called when any of the 'constructor arguments' are mutated.
getStart() : Vector2¶
Gets the start position of this arc.
getEnd() : Vector2¶
Gets the end position of this arc.
getStartTangent() : Vector2¶
Gets the unit vector tangent to this arc at the start point.
getEndTangent() : Vector2¶
Gets the unit vector tangent to the arc at the end point.
getActualEndAngle() : number¶
Gets the end angle in radians.
getIsFullPerimeter() : boolean¶
Returns a boolean value that indicates if the arc wraps up by more than two Pi.
getAngleDifference() : number¶
Returns an angle difference that represents how "much" of the circle our arc covers.
The answer is always greater or equal to zero The answer can exceed two Pi
getBounds() : Bounds2¶
Returns the bounds of this segment.
getNondegenerateSegments() : Arc[]¶
Returns a list of non-degenerate segments that are equivalent to this segment. Generally gets rid (or simplifies) invalid or repeated segments.
mapAngle( angle : number ) : number¶
Maps a contained angle to between [startAngle,actualEndAngle), even if the end angle is lower.
tAtAngle( angle : number ) : number¶
Returns the parametrized value t for a given angle. The value t should range from 0 to 1 (inclusive).
angleAt( t : number ) : number¶
Returns the angle for the parametrized t value. The t value should range from 0 to 1 (inclusive).
positionAtAngle( angle : number ) : Vector2¶
Returns the position of this arc at angle.
tangentAtAngle( angle : number ) : Vector2¶
Returns the normalized tangent of this arc. The tangent points outward (inward) of this arc for clockwise (anticlockwise) direction.
containsAngle( angle : number ) : boolean¶
Returns whether the given angle is contained by the arc (whether a ray from the arc's origin going in that angle will intersect the arc).
getSVGPathFragment() : string¶
Returns a string containing the SVG path. assumes that the start point is already provided, so anything that calls this needs to put the M calls first
strokeLeft( lineWidth : number ) : Arc[]¶
Returns an array of arcs that will draw an offset on the logical left side
strokeRight( lineWidth : number ) : Arc[]¶
Returns an array of arcs that will draw an offset curve on the logical right side
getInteriorExtremaTs() : number[]¶
Returns a list of t values where dx/dt or dy/dt is 0 where 0 < t < 1. subdividing on these will result in monotonic segments Does not include t=0 and t=1
intersection( ray : Ray2 ) : RayIntersection[]¶
Hit-tests this segment with the ray. An array of all intersections of the ray with this segment will be returned. For details, see the documentation in Segment.js
windingIntersection( ray : Ray2 ) : number¶
Returns the resultant winding number of this ray intersecting this arc.
writeToContext( context : CanvasRenderingContext2D )¶
Draws this arc to the 2D Canvas context, assuming the context's current location is already at the start point
transformed( matrix : Matrix3 ) : Arc | EllipticalArc¶
Returns a new copy of this arc, transformed by the given matrix.
TODO: test various transform types, especially rotations, scaling, shears, etc. https://github.com/phetsims/kite/issues/76
getSignedAreaFragment() : number¶
Returns the contribution to the signed area computed using Green's Theorem, with P=-y/2 and Q=x/2.
NOTE: This is this segment's contribution to the line integral (-y/2 dx + x/2 dy).
reversed() : Arc¶
Returns a reversed copy of this segment (mapping the parametrization from [0,1] => [1,0]).
getArcLength() : number¶
Returns the arc length of the segment.
toPiecewiseLinearOrArcSegments() : Segment[]¶
We can handle this simply by returning ourselves.
serialize() : SerializedArc¶
Returns an object form that can be turned back into a segment with the corresponding deserialize method.
getOverlaps( segment : Segment, epsilon ) : Overlap[] | null¶
Determine whether two lines overlap over a continuous section, and if so finds the a,b pair such that p( t ) === q( a * t + b ).
@param segment @param [epsilon] - Will return overlaps only if no two corresponding points differ by this amount or more in one component. @returns - The solution, if there is one (and only one)
getConicMatrix() : Matrix3¶
Returns the matrix representation of the conic section of the circle. See https://en.wikipedia.org/wiki/Matrix_representation_of_conic_sections
Static Methods¶
deserialize( obj : SerializedArc ) : Arc¶
Returns an Arc from the serialized representation.
computeActualEndAngle( startAngle : number, endAngle : number, anticlockwise : boolean ) : number¶
Determines the actual end angle (compared to the start angle).
Normalizes the sign of the angles, so that the sign of ( endAngle - startAngle ) matches whether it is anticlockwise.
getAngularOverlaps( startAngle1 : number, endAngle1 : number, startAngle2 : number, endAngle2 : number ) : Overlap[]¶
Determine whether two Arcs overlap over continuous sections, and if so finds the a,b pairs such that p( t ) === q( a * t + b ).
@param startAngle1 - Start angle of arc 1 @param endAngle1 - "Actual" end angle of arc 1 @param startAngle2 - Start angle of arc 2 @param endAngle2 - "Actual" end angle of arc 2 @returns - Any overlaps (from 0 to 2)
getOverlaps( arc1 : Arc, arc2 : Arc ) : Overlap[]¶
Determine whether two Arcs overlap over continuous sections, and if so finds the a,b pairs such that p( t ) === q( a * t + b ).
@returns - Any overlaps (from 0 to 2)
getCircleIntersectionPoint( center1 : Vector2, radius1 : number, center2 : Vector2, radius2 : number ) : Vector2[]¶
Returns the points of intersections between two circles.
@param center1 - Center of the first circle @param radius1 - Radius of the first circle @param center2 - Center of the second circle @param radius2 - Radius of the second circle
intersect( a : Arc, b : Arc ) : SegmentIntersection[]¶
Returns any (finite) intersection between the two arc segments.
createFromPoints( startPoint : Vector2, middlePoint : Vector2, endPoint : Vector2 ) : Segment¶
Creates an Arc (or if straight enough a Line) segment that goes from the startPoint to the endPoint, touching the middlePoint somewhere between the two.
Type ClosestToPointResult¶
Class Cubic¶
Cubic Bezier segment.
See http://www.cis.usouthal.edu/~hain/general/Publications/Bezier/BezierFlattening.pdf for info
Good reference: http://cagd.cs.byu.edu/~557/text/ch2.pdf
@author Jonathan Olson <jonathan.olson@colorado.edu>
Constructor¶
new Cubic( start : Vector2, control1 : Vector2, control2 : Vector2, end : Vector2 )¶
Instance Methods¶
setStart( start : Vector2 ) : this¶
Sets the start point of the Cubic.
getStart() : Vector2¶
Returns the start of this Cubic.
setControl1( control1 : Vector2 ) : this¶
Sets the first control point of the Cubic.
getControl1() : Vector2¶
Returns the first control point of this Cubic.
setControl2( control2 : Vector2 ) : this¶
Sets the second control point of the Cubic.
getControl2() : Vector2¶
Returns the second control point of this Cubic.
setEnd( end : Vector2 ) : this¶
Sets the end point of the Cubic.
getEnd() : Vector2¶
Returns the end of this Cubic.
positionAt( t : number ) : Vector2¶
Returns the position parametrically, with 0 <= t <= 1.
NOTE: positionAt( 0 ) will return the start of the segment, and positionAt( 1 ) will return the end of the segment.
This method is part of the Segment API. See Segment.js's constructor for more API documentation.
tangentAt( t : number ) : Vector2¶
Returns the non-normalized tangent (dx/dt, dy/dt) of this segment at the parametric value of t, with 0 <= t <= 1.
NOTE: tangentAt( 0 ) will return the tangent at the start of the segment, and tangentAt( 1 ) will return the tangent at the end of the segment.
This method is part of the Segment API. See Segment.js's constructor for more API documentation.
curvatureAt( t : number ) : number¶
Returns the signed curvature of the segment at the parametric value t, where 0 <= t <= 1.
The curvature will be positive for visual clockwise / mathematical counterclockwise curves, negative for opposite curvature, and 0 for no curvature.
NOTE: curvatureAt( 0 ) will return the curvature at the start of the segment, and curvatureAt( 1 ) will return the curvature at the end of the segment.
This method is part of the Segment API. See Segment.js's constructor for more API documentation.
subdivided( t : number ) : Cubic[]¶
Returns an array with up to 2 sub-segments, split at the parametric t value. Together (in order) they should make up the same shape as the current segment.
This method is part of the Segment API. See Segment.js's constructor for more API documentation.
invalidate()¶
Clears cached information, should be called when any of the 'constructor arguments' are mutated.
getStartTangent() : Vector2¶
Gets the start position of this cubic polynomial.
getEndTangent() : Vector2¶
Gets the end position of this cubic polynomial.
getR() : Vector2¶
TODO: documentation https://github.com/phetsims/kite/issues/76
getS() : Vector2¶
TODO: documentation https://github.com/phetsims/kite/issues/76
getTCusp() : number¶
Returns the parametric t value for the possible cusp location. A cusp may or may not exist at that point.
getTDeterminant() : number¶
Returns the determinant value for the cusp, which indicates the presence (or lack of presence) of a cusp.
getTInflection1() : number¶
Returns the parametric t value for the potential location of the first possible inflection point.
getTInflection2() : number¶
Returns the parametric t value for the potential location of the second possible inflection point.
getQuadratics() : Quadratic[] | null¶
If there is a cusp, this cubic will consist of one or two quadratic segments, typically "start => cusp" and "cusp => end".
getXExtremaT() : number[]¶
Returns a list of parametric t values where x-extrema exist, i.e. where dx/dt==0. These are candidate locations on the cubic for "maximum X" and "minimum X", and are needed for bounds computations.
getYExtremaT() : number[]¶
Returns a list of parametric t values where y-extrema exist, i.e. where dy/dt==0. These are candidate locations on the cubic for "maximum Y" and "minimum Y", and are needed for bounds computations.
getBounds() : Bounds2¶
Returns the bounds of this segment.
getNondegenerateSegments() : Segment[]¶
Returns a list of non-degenerate segments that are equivalent to this segment. Generally gets rid (or simplifies) invalid or repeated segments.
hasCusp() : boolean¶
Returns whether this cubic has a cusp.
toRS( point : Vector2 ) : Vector2¶
offsetTo( r : number, reverse : boolean ) : Line[]¶
getSVGPathFragment() : string¶
Returns a string containing the SVG path. assumes that the start point is already provided, so anything that calls this needs to put the M calls first
strokeLeft( lineWidth : number ) : Line[]¶
Returns an array of lines that will draw an offset curve on the logical left side
strokeRight( lineWidth : number ) : Line[]¶
Returns an array of lines that will draw an offset curve on the logical right side
getInteriorExtremaTs() : number[]¶
Returns a list of t values where dx/dt or dy/dt is 0 where 0 < t < 1. subdividing on these will result in monotonic segments The list does not include t=0 and t=1
intersection( ray : Ray2 ) : RayIntersection[]¶
Hit-tests this segment with the ray. An array of all intersections of the ray with this segment will be returned. For details, see the documentation in Segment.js
windingIntersection( ray : Ray2 ) : number¶
Returns the winding number for intersection with a ray
writeToContext( context : CanvasRenderingContext2D )¶
Draws the segment to the 2D Canvas context, assuming the context's current location is already at the start point
transformed( matrix : Matrix3 ) : Cubic¶
Returns a new cubic that represents this cubic after transformation by the matrix
degreeReduced( epsilon : number ) : Quadratic | null¶
Returns a degree-reduced quadratic Bezier if possible, otherwise it returns null
getSignedAreaFragment() : number¶
Returns the contribution to the signed area computed using Green's Theorem, with P=-y/2 and Q=x/2.
NOTE: This is this segment's contribution to the line integral (-y/2 dx + x/2 dy).
reversed() : Cubic¶
Returns a reversed copy of this segment (mapping the parametrization from [0,1] => [1,0]).
getSelfIntersection() : SegmentIntersection | null¶
If it exists, returns the point where the cubic curve self-intersects.
@returns - Null if there is no intersection
serialize() : SerializedCubic¶
Returns an object form that can be turned back into a segment with the corresponding deserialize method.
getOverlaps( segment : Segment, epsilon ) : Overlap[] | null¶
Determine whether two lines overlap over a continuous section, and if so finds the a,b pair such that p( t ) === q( a * t + b ).
@param segment @param [epsilon] - Will return overlaps only if no two corresponding points differ by this amount or more in one component. @returns - The solution, if there is one (and only one)
Instance Properties¶
degree : number¶
Degree of this polynomial (cubic)
Static Methods¶
deserialize( obj : SerializedCubic ) : Cubic¶
Returns a Cubic from the serialized representation.
extremaT( v0 : number, v1 : number, v2 : number, v3 : number ) : number[]¶
Finds what t values the cubic extrema are at (if any). This is just the 1-dimensional case, used for multiple purposes
getOverlaps( cubic1 : Cubic, cubic2 : Cubic, epsilon ) : Overlap[]¶
Determine whether two Cubics overlap over a continuous section, and if so finds the a,b pair such that p( t ) === q( a * t + b ).
NOTE: for this particular function, we assume we're not degenerate. Things may work if we can be degree-reduced to a quadratic, but generally that shouldn't be done.
@param cubic1 @param cubic2 @param [epsilon] - Will return overlaps only if no two corresponding points differ by this amount or more in one component. @returns - The solution, if there is one (and only one)
Type DashValues¶
- values: number[]
Parametric (t) values for where dash boundaries exist - arcLength: number
Total arc length for this segment - initiallyInside: boolean
Whether the start of the segment is inside a dash (instead of a gap)
Class EllipticalArc¶
An elliptical arc (a continuous sub-part of an ellipse).
Additional helpful notes: - http://www.w3.org/TR/SVG/implnote.html#PathElementImplementationNotes - http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-ellipse (note: context.ellipse was removed from the Canvas spec)
@author Jonathan Olson <jonathan.olson@colorado.edu>
Constructor¶
new EllipticalArc( center : Vector2, radiusX : number, radiusY : number, rotation : number, startAngle : number, endAngle : number, anticlockwise : boolean )¶
Instance Methods¶
setCenter( center : Vector2 ) : this¶
Sets the center of the EllipticalArc.
getCenter() : Vector2¶
Returns the center of this EllipticalArc.
setRadiusX( radiusX : number ) : this¶
Sets the semi-major radius of the EllipticalArc.
getRadiusX() : number¶
Returns the semi-major radius of this EllipticalArc.
setRadiusY( radiusY : number ) : this¶
Sets the semi-minor radius of the EllipticalArc.
getRadiusY() : number¶
Returns the semi-minor radius of this EllipticalArc.
setRotation( rotation : number ) : this¶
Sets the rotation of the EllipticalArc.
getRotation() : number¶
Returns the rotation of this EllipticalArc.
setStartAngle( startAngle : number ) : this¶
Sets the startAngle of the EllipticalArc.
getStartAngle() : number¶
Returns the startAngle of this EllipticalArc.
setEndAngle( endAngle : number ) : this¶
Sets the endAngle of the EllipticalArc.
getEndAngle() : number¶
Returns the endAngle of this EllipticalArc.
setAnticlockwise( anticlockwise : boolean ) : this¶
Sets the anticlockwise of the EllipticalArc.
getAnticlockwise() : boolean¶
Returns the anticlockwise of this EllipticalArc.
positionAt( t : number ) : Vector2¶
Returns the position parametrically, with 0 <= t <= 1.
NOTE: positionAt( 0 ) will return the start of the segment, and positionAt( 1 ) will return the end of the segment.
This method is part of the Segment API. See Segment.js's constructor for more API documentation.
tangentAt( t : number ) : Vector2¶
Returns the non-normalized tangent (dx/dt, dy/dt) of this segment at the parametric value of t, with 0 <= t <= 1.
NOTE: tangentAt( 0 ) will return the tangent at the start of the segment, and tangentAt( 1 ) will return the tangent at the end of the segment.
This method is part of the Segment API. See Segment.js's constructor for more API documentation.
curvatureAt( t : number ) : number¶
Returns the signed curvature of the segment at the parametric value t, where 0 <= t <= 1.
The curvature will be positive for visual clockwise / mathematical counterclockwise curves, negative for opposite curvature, and 0 for no curvature.
NOTE: curvatureAt( 0 ) will return the curvature at the start of the segment, and curvatureAt( 1 ) will return the curvature at the end of the segment.
This method is part of the Segment API. See Segment.js's constructor for more API documentation.
subdivided( t : number ) : EllipticalArc[]¶
Returns an array with up to 2 sub-segments, split at the parametric t value. Together (in order) they should make up the same shape as the current segment.
This method is part of the Segment API. See Segment.js's constructor for more API documentation.
invalidate()¶
Clears cached information, should be called when any of the 'constructor arguments' are mutated.
getUnitTransform() : Transform3¶
Computes a transform that maps a unit circle into this ellipse's location.
Helpful, since we can get the parametric position of our unit circle (at t), and then transform it with this transform to get the ellipse's parametric position (at t).
getStart() : Vector2¶
Gets the start point of this ellipticalArc
getEnd() : Vector2¶
Gets the end point of this ellipticalArc
getStartTangent() : Vector2¶
Gets the tangent vector (normalized) to this ellipticalArc at the start, pointing in the direction of motion (from start to end)
getEndTangent() : Vector2¶
Gets the tangent vector (normalized) to this ellipticalArc at the end point, pointing in the direction of motion (from start to end)
getActualEndAngle() : number¶
Gets the end angle in radians
getIsFullPerimeter() : boolean¶
Returns a boolean value that indicates if the arc wraps up by more than two Pi
getAngleDifference() : number¶
Returns an angle difference that represents how "much" of the circle our arc covers
The answer is always greater or equal to zero The answer can exceed two Pi
getUnitArcSegment() : Arc¶
A unit arg segment that we can map to our ellipse. useful for hit testing and such.
getBounds() : Bounds2¶
Returns the bounds of this segment.
getNondegenerateSegments() : Segment[]¶
Returns a list of non-degenerate segments that are equivalent to this segment. Generally gets rid (or simplifies) invalid or repeated segments.
mapAngle( angle : number ) : number¶
Maps a contained angle to between [startAngle,actualEndAngle), even if the end angle is lower.
TODO: remove duplication with Arc https://github.com/phetsims/kite/issues/76
tAtAngle( angle : number ) : number¶
Returns the parametrized value t for a given angle. The value t should range from 0 to 1 (inclusive).
TODO: remove duplication with Arc https://github.com/phetsims/kite/issues/76
angleAt( t : number ) : number¶
Returns the angle for the parametrized t value. The t value should range from 0 to 1 (inclusive).
positionAtAngle( angle : number ) : Vector2¶
Returns the position of this arc at angle.
tangentAtAngle( angle : number ) : Vector2¶
Returns the normalized tangent of this arc. The tangent points outward (inward) of this arc for clockwise (anticlockwise) direction.
offsetTo( r : number, reverse : boolean ) : Line[]¶
Returns an array of straight lines that will draw an offset on the logical left (right) side for reverse false (true) It discretizes the elliptical arc in 32 segments and returns an offset curve as a list of lineTos/
@param r - distance @param reverse
getSVGPathFragment() : string¶
Returns a string containing the SVG path. assumes that the start point is already provided, so anything that calls this needs to put the M calls first.
strokeLeft( lineWidth : number ) : Line[]¶
Returns an array of straight lines that will draw an offset on the logical left side.
strokeRight( lineWidth : number ) : Line[]¶
Returns an array of straight lines that will draw an offset curve on the logical right side.
getInteriorExtremaTs() : number[]¶
Returns a list of t values where dx/dt or dy/dt is 0 where 0 < t < 1. subdividing on these will result in monotonic segments Does not include t=0 and t=1.
intersection( ray : Ray2 ) : RayIntersection[]¶
Hit-tests this segment with the ray. An array of all intersections of the ray with this segment will be returned. For details, see the documentation in Segment.js
windingIntersection( ray : Ray2 ) : number¶
Returns the resultant winding number of this ray intersecting this arc.
writeToContext( context : CanvasRenderingContext2D )¶
Draws this arc to the 2D Canvas context, assuming the context's current location is already at the start point
transformed( matrix : Matrix3 ) : EllipticalArc¶
Returns this elliptical arc transformed by a matrix
getSignedAreaFragment() : number¶
Returns the contribution to the signed area computed using Green's Theorem, with P=-y/2 and Q=x/2.
NOTE: This is this segment's contribution to the line integral (-y/2 dx + x/2 dy).
reversed() : EllipticalArc¶
Returns a reversed copy of this segment (mapping the parametrization from [0,1] => [1,0]).
serialize() : SerializedEllipticalArc¶
Returns an object form that can be turned back into a segment with the corresponding deserialize method.
getOverlaps( segment : Segment, epsilon ) : Overlap[] | null¶
Determine whether two lines overlap over a continuous section, and if so finds the a,b pair such that p( t ) === q( a * t + b ).
@param segment @param [epsilon] - Will return overlaps only if no two corresponding points differ by this amount or more in one component. @returns - The solution, if there is one (and only one)
getConicMatrix() : Matrix3¶
Returns the matrix representation of the conic section of the ellipse. See https://en.wikipedia.org/wiki/Matrix_representation_of_conic_sections
Static Methods¶
deserialize( obj : SerializedEllipticalArc ) : EllipticalArc¶
Returns an EllipticalArc from the serialized representation.
getOverlapType( a : EllipticalArc, b : EllipticalArc, epsilon ) : EllipticalArcOverlapType¶
Returns what type of overlap is possible based on the center/radii/rotation. We ignore the start/end angles and anticlockwise information, and determine if the FULL ellipses overlap.
getOverlaps( a : EllipticalArc, b : EllipticalArc ) : Overlap[]¶
Determine whether two elliptical arcs overlap over continuous sections, and if so finds the a,b pairs such that p( t ) === q( a * t + b ).
@returns - Any overlaps (from 0 to 2)
intersect( a : EllipticalArc, b : EllipticalArc, epsilon ) : SegmentIntersection[]¶
Returns any (finite) intersection between the two elliptical arc segments.
computeUnitMatrix( center : Vector2, radiusX : number, radiusY : number, rotation : number ) : Matrix3¶
Matrix that transforms the unit circle into our ellipse
computeUnitTransform( center : Vector2, radiusX : number, radiusY : number, rotation : number ) : Transform3¶
Transforms the unit circle into our ellipse.
adapted from http://www.w3.org/TR/SVG/implnote.html#PathElementImplementationNotes
Class EllipticalArcOverlapType¶
Static Properties¶
MATCHING_OVERLAP : EllipticalArcOverlapType¶
(readonly)
radiusX of one equals radiusX of the other, with equivalent centers and rotations to work
OPPOSITE_OVERLAP : EllipticalArcOverlapType¶
(readonly)
radiusX of one equals radiusY of the other, with equivalent centers and rotations to work
NONE : EllipticalArcOverlapType¶
(readonly)
no overlap
enumeration : Enumeration¶
(readonly)
Class KiteLine¶
A line segment (all points directly between the start and end point)
@author Jonathan Olson <jonathan.olson@colorado.edu>
Constructor¶
new KiteLine( start : Vector2, end : Vector2 )¶
Instance Methods¶
setStart( start : Vector2 ) : this¶
Sets the start point of the Line.
getStart() : Vector2¶
Returns the start of this Line.
setEnd( end : Vector2 ) : this¶
Sets the end point of the Line.
getEnd() : Vector2¶
Returns the end of this Line.
positionAt( t : number ) : Vector2¶
Returns the position parametrically, with 0 <= t <= 1.
NOTE: positionAt( 0 ) will return the start of the segment, and positionAt( 1 ) will return the end of the segment.
This method is part of the Segment API. See Segment.js's constructor for more API documentation.
tangentAt( t : number ) : Vector2¶
Returns the non-normalized tangent (dx/dt, dy/dt) of this segment at the parametric value of t, with 0 <= t <= 1.
NOTE: tangentAt( 0 ) will return the tangent at the start of the segment, and tangentAt( 1 ) will return the tangent at the end of the segment.
This method is part of the Segment API. See Segment.js's constructor for more API documentation.
curvatureAt( t : number ) : number¶
Returns the signed curvature of the segment at the parametric value t, where 0 <= t <= 1.
The curvature will be positive for visual clockwise / mathematical counterclockwise curves, negative for opposite curvature, and 0 for no curvature.
NOTE: curvatureAt( 0 ) will return the curvature at the start of the segment, and curvatureAt( 1 ) will return the curvature at the end of the segment.
This method is part of the Segment API. See Segment.js's constructor for more API documentation.
subdivided( t : number ) : Segment[]¶
Returns an array with up to 2 sub-segments, split at the parametric t value. Together (in order) they should make up the same shape as the current segment.
This method is part of the Segment API. See Segment.js's constructor for more API documentation.
invalidate()¶
Clears cached information, should be called when any of the 'constructor arguments' are mutated.
getStartTangent() : Vector2¶
Returns a normalized unit vector that is tangent to this line (at the starting point) the unit vectors points toward the end points.
getEndTangent() : Vector2¶
Returns the normalized unit vector that is tangent to this line same as getStartTangent, since this is a straight line
getBounds() : Bounds2¶
Returns the bounds of this segment.
getBoundsWithTransform( matrix : Matrix3 ) : Bounds2¶
Returns the bounding box for this transformed Line
getNondegenerateSegments() : Segment[]¶
Returns a list of non-degenerate segments that are equivalent to this segment. Generally gets rid (or simplifies) invalid or repeated segments.
getSVGPathFragment() : string¶
Returns a string containing the SVG path. assumes that the start point is already provided, so anything that calls this needs to put the M calls first
strokeLeft( lineWidth : number ) : Line[]¶
Returns an array of Line that will draw an offset curve on the logical left side
strokeRight( lineWidth : number ) : Line[]¶
Returns an array of Line that will draw an offset curve on the logical right side
getInteriorExtremaTs() : number[]¶
In general, this method returns a list of t values where dx/dt or dy/dt is 0 where 0 < t < 1. subdividing on these will result in monotonic segments Since lines are already monotone, it returns an empty array.
intersection( ray : Ray2 ) : RayIntersection[]¶
Hit-tests this segment with the ray. An array of all intersections of the ray with this segment will be returned. For details, see the documentation in Segment.js
windingIntersection( ray : Ray2 ) : number¶
Returns the resultant winding number of a ray intersecting this line.
writeToContext( context : CanvasRenderingContext2D )¶
Draws this line to the 2D Canvas context, assuming the context's current location is already at the start point
transformed( matrix : Matrix3 ) : Line¶
Returns a new Line that represents this line after transformation by the matrix
explicitClosestToPoint( point : Vector2 ) : ClosestToPointResult[]¶
Returns an object that gives information about the closest point (on a line segment) to the point argument
getSignedAreaFragment() : number¶
Returns the contribution to the signed area computed using Green's Theorem, with P=-y/2 and Q=x/2.
NOTE: This is this segment's contribution to the line integral (-y/2 dx + x/2 dy).
reparameterized( a : number, b : number ) : Line¶
Given the current curve parameterized by t, will return a curve parameterized by x where t = a * x + b
reversed() : Line¶
Returns a reversed copy of this segment (mapping the parametrization from [0,1] => [1,0]).
polarToCartesian( options : PiecewiseLinearOptions ) : Segment[]¶
Convert a line in the \((theta,r)\) plane of the form \((\theta_1,r_1)\) to \((\theta_2,r_2)\) and converts to the cartesian coordinate system
E.g. a polar line (0,1) to (2 Pi,1) would be mapped to a circle of radius 1
getArcLength() : number¶
Returns the arc length of the segment.
toPiecewiseLinearOrArcSegments() : Segment[]¶
We can handle this simply by returning ourselves.
serialize() : SerializedLine¶
Returns an object form that can be turned back into a segment with the corresponding deserialize method.
getOverlaps( segment : Segment, epsilon ) : Overlap[] | null¶
Determine whether two lines overlap over a continuous section, and if so finds the a,b pair such that p( t ) === q( a * t + b ).
@param segment @param [epsilon] - Will return overlaps only if no two corresponding points differ by this amount or more in one component. @returns - The solution, if there is one (and only one)
getClosestPoints( point : Vector2 ) : ClosestToPointResult[]¶
Static Methods¶
deserialize( obj : SerializedLine ) : Line¶
Returns a Line from the serialized representation.
getOverlaps( line1 : Line, line2 : Line, epsilon ) : Overlap[]¶
Determine whether two lines overlap over a continuous section, and if so finds the a,b pair such that p( t ) === q( a * t + b ).
@param line1 @param line2 @param [epsilon] - Will return overlaps only if no two corresponding points differ by this amount or more in one component. @returns - The solution, if there is one (and only one)
intersect( a : Line, b : Line ) : SegmentIntersection[]¶
Returns any (finite) intersection between the two line segments.
intersectOther( line : Line, other : Segment ) : SegmentIntersection[]¶
Returns any intersections between a line segment and another type of segment.
This should be more optimized than the general intersection routine of arbitrary segments.
Type PiecewiseLinearOptions¶
- minLevels?: number
how many levels to force subdivisions - maxLevels?: number
prevent subdivision past this level - distanceEpsilon?: number | null
controls level of subdivision by attempting to ensure a maximum (squared) deviation from the curve - curveEpsilon?: number | null
controls level of subdivision by attempting to ensure a maximum curvature change between segments - pointMap?: ( v: Vector2 ) => Vector2
represents a (usually non-linear) transformation applied - methodName?: KeysMatching<Segment, ( options: PiecewiseLinearOptions ) => Segment[]> | KeysMatching<Arc, ( options: PiecewiseLinearOptions ) => Segment[]> | KeysMatching<Cubic, ( options: PiecewiseLinearOptions ) => Segment[]> | KeysMatching<EllipticalArc, ( options: PiecewiseLinearOptions ) => Segment[]> | KeysMatching<Line, ( options: PiecewiseLinearOptions ) => Segment[]> | KeysMatching<Quadratic, ( options: PiecewiseLinearOptions ) => Segment[]>
if the method name is found on the segment, it is called with the expected signature function( options ) : Array[Segment] instead of using our brute-force logic
Class Quadratic¶
Quadratic Bezier segment
Good reference: http://cagd.cs.byu.edu/~557/text/ch2.pdf
@author Jonathan Olson <jonathan.olson@colorado.edu>
Constructor¶
new Quadratic( start : Vector2, control : Vector2, end : Vector2 )¶
Instance Methods¶
setStart( start : Vector2 ) : this¶
Sets the start point of the Quadratic.
getStart() : Vector2¶
Returns the start of this Quadratic.
setControl( control : Vector2 ) : this¶
Sets the control point of the Quadratic.
getControl() : Vector2¶
Returns the control point of this Quadratic.
setEnd( end : Vector2 ) : this¶
Sets the end point of the Quadratic.
getEnd() : Vector2¶
Returns the end of this Quadratic.
positionAt( t : number ) : Vector2¶
Returns the position parametrically, with 0 <= t <= 1.
NOTE: positionAt( 0 ) will return the start of the segment, and positionAt( 1 ) will return the end of the segment.
This method is part of the Segment API. See Segment.js's constructor for more API documentation.
tangentAt( t : number ) : Vector2¶
Returns the non-normalized tangent (dx/dt, dy/dt) of this segment at the parametric value of t, with 0 <= t <= 1.
NOTE: tangentAt( 0 ) will return the tangent at the start of the segment, and tangentAt( 1 ) will return the tangent at the end of the segment.
This method is part of the Segment API. See Segment.js's constructor for more API documentation.
curvatureAt( t : number ) : number¶
Returns the signed curvature of the segment at the parametric value t, where 0 <= t <= 1.
The curvature will be positive for visual clockwise / mathematical counterclockwise curves, negative for opposite curvature, and 0 for no curvature.
NOTE: curvatureAt( 0 ) will return the curvature at the start of the segment, and curvatureAt( 1 ) will return the curvature at the end of the segment.
This method is part of the Segment API. See Segment.js's constructor for more API documentation.
subdivided( t : number ) : Quadratic[]¶
Returns an array with up to 2 sub-segments, split at the parametric t value. Together (in order) they should make up the same shape as the current segment.
This method is part of the Segment API. See Segment.js's constructor for more API documentation.
invalidate()¶
Clears cached information, should be called when any of the 'constructor arguments' are mutated.
getStartTangent() : Vector2¶
Returns the tangent vector (normalized) to the segment at the start, pointing in the direction of motion (from start to end)
getEndTangent() : Vector2¶
Returns the tangent vector (normalized) to the segment at the end, pointing in the direction of motion (from start to end)
getTCriticalX() : number¶
getTCriticalY() : number¶
getNondegenerateSegments() : Segment[]¶
Returns a list of non-degenerate segments that are equivalent to this segment. Generally gets rid (or simplifies) invalid or repeated segments.
getBounds() : Bounds2¶
Returns the bounds of this segment.
offsetTo( r : number, reverse : boolean ) : Quadratic[]¶
Returns an array of quadratic that are offset to this quadratic by a distance r
@param r - distance @param reverse
degreeElevated() : Cubic¶
Elevation of this quadratic Bezier curve to a cubic Bezier curve
approximateOffset( r : number ) : Quadratic¶
@param r - distance
getSVGPathFragment() : string¶
Returns a string containing the SVG path. assumes that the start point is already provided, so anything that calls this needs to put the M calls first
strokeLeft( lineWidth : number ) : Quadratic[]¶
Returns an array of lines that will draw an offset curve on the logical left side
strokeRight( lineWidth : number ) : Quadratic[]¶
Returns an array of lines that will draw an offset curve on the logical right side
getInteriorExtremaTs() : number[]¶
intersection( ray : Ray2 ) : RayIntersection[]¶
Hit-tests this segment with the ray. An array of all intersections of the ray with this segment will be returned. For details, see the documentation in Segment.js
windingIntersection( ray : Ray2 ) : number¶
Returns the winding number for intersection with a ray
writeToContext( context : CanvasRenderingContext2D )¶
Draws the segment to the 2D Canvas context, assuming the context's current location is already at the start point
transformed( matrix : Matrix3 ) : Quadratic¶
Returns a new quadratic that represents this quadratic after transformation by the matrix
getSignedAreaFragment() : number¶
Returns the contribution to the signed area computed using Green's Theorem, with P=-y/2 and Q=x/2.
NOTE: This is this segment's contribution to the line integral (-y/2 dx + x/2 dy).
reparameterized( a : number, b : number ) : Quadratic¶
Given the current curve parameterized by t, will return a curve parameterized by x where t = a * x + b
reversed() : Quadratic¶
Returns a reversed copy of this segment (mapping the parametrization from [0,1] => [1,0]).
serialize() : SerializedQuadratic¶
Returns an object form that can be turned back into a segment with the corresponding deserialize method.
getOverlaps( segment : Segment, epsilon ) : Overlap[] | null¶
Determine whether two lines overlap over a continuous section, and if so finds the a,b pair such that p( t ) === q( a * t + b ).
@param segment @param [epsilon] - Will return overlaps only if no two corresponding points differ by this amount or more in one component. @returns - The solution, if there is one (and only one)
Instance Properties¶
degree : number¶
Degree of the polynomial (quadratic)
Static Methods¶
deserialize( obj : SerializedQuadratic ) : Quadratic¶
Returns a Quadratic from the serialized representation.
extremaT( start : number, control : number, end : number ) : number¶
One-dimensional solution to extrema
getOverlaps( quadratic1 : Quadratic, quadratic2 : Quadratic, epsilon ) : Overlap[]¶
Determine whether two Quadratics overlap over a continuous section, and if so finds the a,b pair such that p( t ) === q( a * t + b ).
NOTE: for this particular function, we assume we're not degenerate. Things may work if we can be degree-reduced to a quadratic, but generally that shouldn't be done.
@param quadratic1 @param quadratic2 @param [epsilon] - Will return overlaps only if no two corresponding points differ by this amount or more in one component. @returns - The solution, if there is one (and only one)
Type SerializedArc¶
- type: "Arc"
- centerX: number
- centerY: number
- radius: number
- startAngle: number
- endAngle: number
- anticlockwise: boolean
Type SerializedCubic¶
- type: "Cubic"
- startX: number
- startY: number
- control1X: number
- control1Y: number
- control2X: number
- control2Y: number
- endX: number
- endY: number
Type SerializedEllipticalArc¶
- type: "EllipticalArc"
- centerX: number
- centerY: number
- radiusX: number
- radiusY: number
- rotation: number
- startAngle: number
- endAngle: number
- anticlockwise: boolean
Type SerializedLine¶
- type: "Line"
- startX: number
- startY: number
- endX: number
- endY: number
Type SerializedQuadratic¶
- type: "Quadratic"
- startX: number
- startY: number
- controlX: number
- controlY: number
- endX: number
- endY: number
Type SerializedSegment¶
SerializedArc | SerializedCubic | SerializedEllipticalArc | SerializedLine | SerializedQuadratic
Source Code¶
See the source for Segment.ts in the kite repository.