UNPKG

plotboilerplate

Version:

A simple javascript plotting boilerplate for 2d stuff.

151 lines (150 loc) 7.67 kB
/** * A function to detect contour lines from 3D terrain data. * * For usage see demo `./demos/48-contour-plot`. * * @requires detectPaths * @requires GenericPath * @author Ikaros Kappler * @date 2023-11-05 * @modified 2023-11-20 Addig path detection on a triangle based grid. * @version 1.0.0 */ import { Line } from "../../Line"; import { IDataGrid2d } from "../datastructures/DataGrid2d"; import { GenericPath } from "../datastructures/GenericPath"; export declare class ContourLineDetection { private dataGrid; private rawLinearPathSegments; static CLOSE_GAP_TYPE_NONE: number; static CLOSE_GAP_TYPE_ABOVE: number; static CLOSE_GAP_TYPE_BELOW: number; debugMode: boolean; /** * Creates a new instance for calculating contour lines from the given data grid. * @param {IDataGrid2d<number>} dataGrid - The data grid to use. Must not contain any NaN or null values. * @param {boolean=?} debugMode - (optional) Pass `true` to log warnings on (rare) critical edge cases where the algorithm might fail. */ constructor(dataGrid: IDataGrid2d<number>, debugMode?: boolean); /** * Detect contour paths from the underlying data source. * * @param {number} criticalHeightValue - The height value. If above data's maximum or below data's minimum then the result will be empty (no intersections). * @param {number} options.closeGapType - `CLOSE_GAP_TYPE_NONE` or `CLOSE_GAP_TYPE_ABOVE` or `CLOSE_GAP_TYPE_BELOW`. * @param {boolean=false} options.useTriangles - If set to true the detection will split each face3 quad into two triangle faces. * @param {pathDetectEpsilon=0.000001} options.pathDetectEpsilon - (optional) The epsilon to tell if two points are located 'in the same place'. Used for connected path detection. If not specified the value `0.0000001` is used. * @param {pointEliminationEpsilon=0.0000001} options.pointEliminationEpsilon - (optional) The epsilon for duplicate point elimination (default is 0.000001). * @param {function?} onRawSegmentsDetected - (optional) Get the interim result of all detected single lines before path detection starts; DO NOT MODIFY the array. * @returns {Array<GenericPath>} - A list of connected paths that resemble the contour lines of the data/terrain at the given height value. */ detectContourPaths(criticalHeightValue: number, options?: { closeGapType: number; useTriangles?: boolean; pointEliminationEpsilon?: number; pathDetectEpsilon?: number; onRawSegmentsDetected?: (rawSegmentsDoNotModifiy: Array<Line>) => void; }): Array<GenericPath>; /** * This function will calculate a single intersecion line of the given face4 data * segment. If the given face does not intersect with the plane at the given `heightValue` * then no segments will be stored. * * @param {number} xIndex - The x position (index) of the data face. * @param {number} yIndex - The y position (index) of the data face. * @param {[[number,number],[number,number]]} heightFace - The data sample that composes the face4 as a two-dimensional number array. * @param {number} heightValue - The height value of the intersection plane to check for. * @returns {Line|null} */ private findHeight4FaceIntersectionLine; /** * This function will calculate a single intersecion line of the given face4 data * segment. If the given face does not intersect with the plane at the given `heightValue` * then no segments will be stored. * * @param {number} xIndex - The x position (index) of the data face. * @param {number} yIndex - The y position (index) of the data face. * @param {[[number,number],[number,number]]} heightFace - The data sample that composes the face4 as a two-dimensional number array. * @param {number} heightValue - The height value of the intersection plane to check for. * @returns {Line|null} */ private findHeightFaceIntersectionLines; /** * This function will calculate a single intersecion line of the given face3 data * segment. If the given face does not intersect with the plane at the given `heightValue` * then no segments will be stored. * * @param {number} xIndexA - The x position (index) of the first triangle data point. * @param {number} yIndexA - The y position (index) of the first triangle data point. * @param {[[number,number],[number,number]]} heightFace - The data sample that composes the face4 as a two-dimensional number array. * @param {number} heightValue - The height value of the intersection plane to check for. * @returns {Line|null} */ private findHeighteFace3IntersectionLine; /** * This procedure will look at the face4 at the ((x,y),(nextX,nextY)) position – which are four values – * and determines the local contour lines for these cases. * * This is used to detect and calculate edge cases on the borders of the underliying height data: * * left and right border (x=0, x=data.xSegmentCount) * * top and bottom border (x=y, x=data.ySegmentCount) * * Resulting path segments will be stored in the global `rawLinearPathSegments` array for further processing. * * @param {number} x * @param {number} y * @param {number} nextX * @param {number} nextY * @param {number} criticalHeightValue * @param {number} closeGapType - CLOSE_GAP_TYPE_ABOVE or CLOSE_GAP_TYPE_BELOW. * @return {void} */ detectAboveBelowLerpSegment(x: number, y: number, nextX: number, nextY: number, criticalHeightValue: number, closeGapType: number): void; /** * Checks if both value are on the same side of the critical value (above or below). The `closeGapType` * indictes if `CLOSE_GAP_TYPE_BELOW` or `CLOSE_GAP_TYPE_ABOVE` should be used as a rule. * * @param {number} valueA * @param {number} valueB * @param {number} criticalValue * @param {number} closeGapType * @returns {boolean} */ private areBothValuesOnRequiredPlaneSide; /** * Test if a given numeric value (`curValue`) is between the given values `valA` and `valB`. * Value A and B don't need to be in ascending order, so `valA <= curValue <= valB` and `valB <= curvalue <= valA` * will do the job. * * @param {number} valA - The first of the two bounds. * @param {number} valB - The second of the two bounds. * @param {number} curValue - The value to check if it is between (or equal) to the given bounds. * @returns {boolean} */ private isBetween; /** * Get a 'lerp' value - which is some sort of percentage/ratio for the `curValue` inside the * range of the given interval `[valA ... valB]`. * * Examples: * * getLerpRatio(0,100,50) === 0.5 * * getLerpRatio(50,100,75) === 0.5 * * getLerpRatio(0,100,0) === 0.0 * * getLerpRatio(0,100,100) === 1.0 * * getLerpRatio(0,100,-50) === -0.5 * * @param {number} valA * @param {number} valB * @param {number} curValue * @returns */ private getLerpRatio; /** * Helper function to lerp a numeric value. * * @param {number} min - The min (start) value. Doesn't necesarily need to be the smaller one. * @param {number} max - The max (end) value. Doesn't necesarily need to be the larger one. * @param {number} ratio - The lerp ratio; usually a value between 0.0 and 1.0, but other values a valid for linear interpolation, too. * @returns {number} */ private lerp; }