// Based on the code from https://github.com/jasondavies/conrec.js /** * Copyright (c) 2010, Jason Davies. * * All rights reserved. This code is based on Bradley White's Java version, * which is in turn based on Nicholas Yue's C++ version, which in turn is based * on Paul D. Bourke's original Fortran version. See below for the respective * copyright notices. * * See http://local.wasp.uwa.edu.au/~pbourke/papers/conrec/ for the original * paper by Paul D. Bourke. * * The vector conversion code is based on http://apptree.net/conrec.htm by * Graham Cox. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * Neither the name of the nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Copyright (c) 1996-1997 Nicholas Yue * * This software is copyrighted by Nicholas Yue. This code is based on Paul D. * Bourke's CONREC.F routine. * * The authors hereby grant permission to use, copy, and distribute this * software and its documentation for any purpose, provided that existing * copyright notices are retained in all copies and that this notice is * included verbatim in any distributions. Additionally, the authors grant * permission to modify this software and its documentation for any purpose, * provided that such modifications are not distributed without the explicit * consent of the authors and that existing copyright notices are retained in * all copies. Some of the algorithms implemented by this software are * patented, observe all applicable patent law. * * IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT * OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, * EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS * PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR * MODIFICATIONS. */ import type { Point, SequenceNode } from './ContourBuilder.ts'; import { ContourBuilder } from './ContourBuilder.ts'; export interface ShapeContour { level: number; k: number; lines: Point[]; } export class ShapeContourDrawer { private contours: ContourBuilder[]; private swapAxes: boolean; constructor(levels: number[], swapAxes: boolean) { this.contours = new Array(levels.length); for (let i = 0; i < levels.length; i++) { this.contours[i] = new ContourBuilder(levels[i]); } this.swapAxes = swapAxes; } drawContour( x1: number, y1: number, x2: number, y2: number, z: number, k: number, ) { if (!this.swapAxes) { this.contours[k].addSegment({ x: y1, y: x1 }, { x: y2, y: x2 }); } else { this.contours[k].addSegment({ x: x1, y: y1 }, { x: x2, y: y2 }); } } getContour() { const l: ShapeContour[] = []; const a = this.contours; for (let k = 0; k < a.length; k++) { let s = a[k].s; const level = a[k].level; while (s) { let h: SequenceNode | null = s.head; const l2: ShapeContour = { lines: [], level, k }; while (h?.p) { l2.lines.push(h.p); h = h.next; } l.push(l2); s = s.next; } } return l; } }