Example #1
0
  constructor(container: HTMLElement, viewSize: [number, number]) {
    // Internal UI state
    this._viewSize = viewSize;
    this._container = container;
    this._canvasSize = [viewSize[0] / 2, viewSize[1]];
    this._canvasBounds = new Rect(
      Coords2d.fromXY(0, this._canvasSize[1]),
      OffsetCoords2d.fromDxDy(this._canvasSize[0], -this._canvasSize[1])
    );

    this._needsRedraw = false;

    this.gluingBounds = Rect.fromDimensions(2, 2);
    this.editMode = 'triangle';

    // Internal array to store the embedded 3-d triangles.
    this._distance = 3;
    this._triangle = Triangle2d.fromCoords(
      Coords2d.origin(),
      Coords2d.fromXY(1, 0),
      Coords2d.fromXY(0.5, Math.sqrt(3)/4)
    );
    this._rotation = Quaternion.fromReal(1);
    this._gluing = TriangleTetraGluing.fromEdgeIndexAndGluePoint(0, 0);
    this._refreshEmbedding();
  }
Example #2
0
export function addLinesForTriangle(
    elements: Array<Renderable>, origin: Coords2d, sign: number) {
  let v0 = origin;
  let v1 = Coords2d.fromXY(origin.x + sign*triWidth, origin.y);
  let v2 = Coords2d.fromXY(
    origin.x + sign*triWidth/2, origin.y + sign * triHeight);
  elements.push(new Line(v0, v1));
  elements.push(new Line(v1, v2));
  elements.push(new Line(v2, v0));

  elements.push(new Line(
    origin.plus(triBase[0].asOffsetFromOrigin().timesReal(sign)),
    origin.plus(triRight.asOffsetFromOrigin().timesReal(sign))));

  let inner = [
    triInner[0].asOffsetFromOrigin(),
    triInner[1].asOffsetFromOrigin()];
  elements.push(new Line(
    origin.plus(triLeft.asOffsetFromOrigin().timesReal(sign)),
    origin.plus(inner[0].timesReal(sign))));

  elements.push(new Line(
    origin.plus(triBase[2].asOffsetFromOrigin().timesReal(sign)),
    origin.plus(inner[1].timesReal(sign))));

  return elements;
}
Example #3
0
  static fromSideLengths (a: number, b: number, c: number): Triangle2d {
    //throw "Triangle.fromSideLengths unimplemented";

    // Numerically stable Heron's formula:
    var area = Math.sqrt(
      (a + (b + c)) * (c - (a - b)) * (c + (a - b)) * (a + (b - c)));

    // Now treat b as the length of the base, with the first vertex of the
    // triangle being the apex, which moves counterclockwise along a.
    var ascent = 2 * area / b;
    // The right-side root from the left side of the base.
    var rightLeft = b - Math.sqrt(c - ascent * ascent);
    // The left-side root from the right side of the base.
    var leftRight = Math.sqrt(a - ascent * ascent);
    var apexX;
    if (rightLeft < 0) {
      apexX = rightLeft;
    } else {
      apexX = leftRight;
    }
    return Triangle2d.fromCoords(
      Coords2d.fromXY(apexX, ascent),
      Coords2d.fromXY(0, 0),
      Coords2d.fromXY(b, 0)
    );
  }
Example #4
0
  elementsToRender (frameRect: AxisRect): Array<CanvasRender.Renderable> {
    console.log("BilliardsFlowModel.elementsToRender");

    let image = new ImageRendering(
      AxisRect.fromXYWH(0, 0, 1, 1),
      this.gridSize,
      (imageData: ImageData) => {
        let width = this.gridSize.width;
        let height = this.gridSize.height;
        //let renderScale = this.renderTarget.canvas.renderScale;
        for (let y = 0; y < height; y++) {
          for (let x = 0; x < width; x++) {
            let val = Math.floor(255.9 * this.grid[y * width + x]);


            let offset = y * width + x;
            //let modelCoords = pixelSpaceToModelSpace.transformCoords(
            //  Coords2d.fromXY(x / renderScale, y / renderScale));
            imageData.data[offset*4 + 0] = val;
            imageData.data[offset*4 + 1] = 0;
            imageData.data[offset*4 + 2] = val;
            imageData.data[offset*4 + 3] = 255;
          }
        }
      });

    let line = new Line(Coords2d.fromXY(0, 0), Coords2d.fromXY(1, 0));


    return [image, line];
  }
Example #5
0
 vertexCoords (): Array<Coords2d> {
   let {x, y} = this.origin;
   let {width, height} = this.size;
   return [
     Coords2d.fromXY(x, y),
     Coords2d.fromXY(x + width, y),
     Coords2d.fromXY(x + width, y + height),
     Coords2d.fromXY(x, y + height)];
 }
Example #6
0
 vertexCoords (): Array<Coords2d> {
   let o = this.origin;
   let d = this.diagonal;
   return [
     Coords2d.fromXY(o.x, o.y),
     Coords2d.fromXY(o.x + d.dx, o.y),
     Coords2d.fromXY(o.x + d.dx, o.y + d.dy),
     Coords2d.fromXY(o.x, o.y + d.dy)];
 }
Example #7
0
export function TriangleForApex(apex: Coords2d): Triangle2d {
  return Triangle2d.fromCoords(
    Coords2d.origin(),
    Coords2d.fromXY(1, 0),
    apex
  );
}
Example #8
0
export function ApexForBaseAngles(a0: number, a1: number): Coords2d {
  let leftTangent =
    OffsetCoords2d.fromPolar(1, a0).rootedAtCoords(Coords2d.origin());
  let rightTangent = OffsetCoords2d.fromPolar(1, Math.PI - a1)
    .rootedAtCoords(Coords2d.fromXY(1, 0));
  return leftTangent.intersectionWith(rightTangent);
}
Example #9
0
  elementsToRender (frameRect: AxisRect): Array<CanvasRender.Renderable> {
    let elements: Array<CanvasRender.Renderable> = [];
    let boundaryRect = AxisRect.fromXYWH(0, 0, this.columnCount, this.rowCount);

    let borderElement = Polygon.fromRect(boundaryRect.addMargin(0.35));
    elements.push(borderElement);

    let colors = ['#eeeeee', '#fae', '#000066'];

    for (let i = 0; i < this.rowCount; i++) {
      let y = (i + 0.5);
      for (let j = 0; j < this.columnCount; j++) {
        let x = (j + 0.5);
        let value = this.grid(this.rowCount - i - 1, j);
        let color = '#333333';
        if (value >= 0 && value < colors.length) {
          color = colors[value];
        }
        let cellRect = AxisRect.fromCenterAndDimensions(
          Coords2d.fromXY(x, y), 1, 1);
        let cellElement = Polygon.fromRect(cellRect.scaleBy(0.9));
        cellElement.style.fillStyle = color;
        cellElement.style.strokeStyle = "";
        elements.push(cellElement);
      }
    }


    return elements;
  }
Example #10
0
      return (newCanvasCoords: Coords2d) => {
        var newModelCoords =
          canvasToModel.transformCoords(newCanvasCoords);
        if (newModelCoords.y < 0.01) {
          newModelCoords.y = 0.01;
        }
        if (newModelCoords.x < 0) {
          newModelCoords.x = 0;
        }
        if (newModelCoords.x > 1) {
          newModelCoords.x = 1;
        }
        var modelDelta = newModelCoords.asOffsetFrom(modelCoords);
        let newApexCoords = originalApexCoords.plus(modelDelta);

        let newSourceY = newApexCoords.y * originalSourceVert;
        let newSourceX = newApexCoords.x +
          (originalSourceHorz - newApexCoords.x) *
          (1.0 - originalSourceVert);

        this.apex = newApexCoords;
        this.source.base = Coords2d.fromXY(newSourceX, newSourceY);
        this.source.offset.dy = originalSource.offset.dy *
          (newApexCoords.y / originalApexCoords.y);
        this.source.offset = this.source.offset.normalized();
        this._needsRedraw = true;
      };
Example #11
0
 _thingie () {
   for (let i = 0; i < this.edgePaths.length; i++) {
     if (!EdgePathIsClosed(this.edgePaths[i])) {
       window.console.log(
         `Warning: edge path ${i} (${this.edgePaths[i]}) is not closed`);
     }
   }
   let edgeSequences = this.edgePaths.map(EdgeSequenceForEdgePath);
   let cutoff = edgeSequences.length - this.highlightCount;
   this.extra = [];
   let h = Math.sqrt(3) / 3;
   let w = 1;
   let tri = this.triangle;
   //let xres = 100;
   //let yres = 50;
   //let dotRadius = 0.007;
   let xres = 200;
   let yres = 100;
   let dotRadius = 0.0045;
   let highlighted = 0;
   let sequenceCounts = edgeSequences.map(() => 0);
   for (let y = 1; y <= yres; y++) {
     for (let x = 0; x <= xres; x++) {
       for (let i = 0; i < edgeSequences.length; i++) {
       //for (let i = edgeSequences.length - 1; i >= 0; i--) {
         let edgeSequence = edgeSequences[i];
         let v = tri.vertexCoords;
         v[2] = Coords2d.fromXY(v[0].x + x * w / xres, v[0].y + y * h / yres);
         let margin = PathMargin(tri, edgeSequence);
         if (margin > 0) {
           let c = CanvasRender.Circle.fromCenterAndRadius(v[2], dotRadius);
           if (i >= cutoff) {
             c.style.fillStyle = '#bb8888';
             highlighted++;
           } else {
             let intensity = Math.min(Math.sqrt(margin), 1);
             let rg = Math.floor(128 * (1 - intensity));
             let b = Math.floor(rg + 255 * intensity);
             c.style.fillStyle = `rgb(${rg},${rg},${b}`;
           }
           this.extra.push(c);
           sequenceCounts[i]++;
           break;
         }
       }
     }
   }
   window.console.log(`${highlighted} points were highlighted`);
   this.sequenceResults = [];
   for (let i = 0; i < sequenceCounts.length; i++) {
     if (sequenceCounts[i] > 0) {
       this.sequenceResults.push([i, sequenceCounts[i]]);
     }
   }
   this._needsRedraw = true;
 }
Example #12
0
  _internalMouseDown(x: number, y: number) {
    var canvasCoords = Coords2d.fromXY(x, y);
    let listener = this.controlPointsCallback(canvasCoords);

    if (listener != null) {
      this._isMouseDown = true;
      this._activePoint = {
        listener: listener,
        canvasCoords: canvasCoords,
      };
    }
  }
Example #13
0
  elementsToRender (modelFrame: AxisRect): Array<Renderable> {
    let horizontalShift = true;
    let trueCenter = false;
    let strokeStyle = '#ff33ee';
    let lineWidth = '2';

    let elements: Array<Renderable> = [];
    console.log("elementsToRender");
    let xOffset = 0;
    if (trueCenter) {
      xOffset += centerOffset;
    }
    if (horizontalShift) {
      xOffset += triWidth / 2;
    }
    for (let i = -10; i <= 10; i++) {
      let origin = Coords2d.fromXY(i * triWidth, 1.5);
      addLinesForTriangle(elements,
        Coords2d.fromXY(origin.x, origin.y), 1);
      addLinesForTriangle(elements,
        Coords2d.fromXY(origin.x + triWidth/2, origin.y + triHeight), -1);

      addLinesForTriangle(elements,
        Coords2d.fromXY(origin.x + xOffset, origin.y - triHeight), 1);
      addLinesForTriangle(elements,
        Coords2d.fromXY(origin.x + triWidth/2 + xOffset, origin.y), -1);
    }

    let rowShift = 0.5721554288609622;
    // The angle of the fundamental interval we want to map to the
    // x axis
    let angle = Math.atan2(-1, rowShift);
    // The distance of each cell along the x axis
    let dx = Math.sqrt(1 + rowShift * rowShift);
    for (let i = -10; i <= 10; i++) {
      let origin = Coords2d.fromXY(i * dx, -3);
      addLinesForSquare(elements, origin, -angle);
      /*for (let j = 0; j < 3; j++) {
        addLinesForSquare(elements,
          Coords2d.fromXY(origin.x + rowShift * j, origin.y - j),
          0);//-angle);
      }*/
    }

    for (let i = 0; i < elements.length; i++) {
      let e = elements[i];
      e.style.strokeStyle = strokeStyle;
      e.style.lineWidth = lineWidth;
    }
    return elements;
  }
Example #14
0
  constructor(renderTarget: RenderTarget) {
    this._renderTarget = renderTarget;
    this.renderParams = new BilliardsPhaseRendererParams();
    this._renderer =
      new BilliardsPhaseRenderer(renderTarget.canvas, _paletteShader);

    this._redrawCounter = 1000;
    this._needsRedraw = false;
    this._controlPointsInterface = null;

    // Exposed properties
    this.numerator = ComplexPoly.fromReal(1);
    this.denominator = ComplexPoly.fromReal(1);
    this.phaseOffset = 0;
    this.modelBounds = AxisRect.fromXYWH(-1, -1, 2, 2);
    this._renderer.renderFrom(this.modelBounds);

    // The coordinates constantOffset was derived from.
    this._offsetCoords = Coords2d.fromXY(0, 0);

    this._createControlInterfaces();

    requestAnimationFrame(this.generateClockTick());
  }
Example #15
0
 static fromCenterAndDimensions (
     center: Coords2d, width: number, height: number): AxisRect {
   let origin = Coords2d.fromXY(center.x - width/2, center.y - height/2);
   let size = Size.fromWH(width, height);
   return new AxisRect(origin, size);
 }
Example #16
0
 static fromXYWH (x: number, y: number, w: number, h: number): AxisRect {
   return new AxisRect(Coords2d.fromXY(x, y), Size.fromWH(w, h));
 }
Example #17
0
 static fromXYWH (x: number, y: number, width: number, height: number): Rect {
   return new Rect(
     Coords2d.fromXY(x, y), OffsetCoords2d.fromDxDy(width, height));
 }
Example #18
0
 // Triangle: the triangle in which we're looking at billiards.
 get triangle (): Triangle2d {
   return Triangle2d.fromCoords(
     Coords2d.origin(),
     Coords2d.fromXY(1, 0),
     this._apex);
 }
Example #19
0
import { ElementsModel } from 'faec/elements_model';
import { Coords2d, OffsetCoords2d } from 'faec/geometry';
import { AxisRect } from 'faec/polygon';

import { Line, Renderable } from 'faec/element_render';

let squareRoot = Math.sqrt(3);
let fourthRoot = Math.sqrt(squareRoot);
// (w, h) are the dimensions of the unit-area equilateral triangle
// with its base aligned with the x axis.
let triWidth = 2 / fourthRoot;
let triHeight = fourthRoot;
let triVerts = [
  Coords2d.origin(),
  Coords2d.fromXY(triWidth, 0),
  Coords2d.fromXY(triWidth / 2, triHeight)];
let triLeft = Coords2d.midpoint(triVerts[0], triVerts[2]);
let triRight = Coords2d.midpoint(triVerts[1], triVerts[2]);

// The horizontal width of the long diagonal, which goes from
// triRight to the base and has length 1.
let diagonalWidth = Math.sqrt(1.0 - triRight.y * triRight.y);
let diagonal = OffsetCoords2d.fromDxDy(diagonalWidth, triRight.y);
let triBase = [
  Coords2d.fromXY(triRight.x - diagonalWidth, 0),
  Coords2d.fromXY((triRight.x - diagonalWidth) * 2, 0),
  Coords2d.fromXY((triRight.x - diagonalWidth) + triWidth/2, 0)];

// The offset of the center base point from the geometric center
// of the edge.
Example #20
0
 _internalMouseMove(x: number, y: number) {
   if (this._activePoint != null) {
     this._activePoint.listener(Coords2d.fromXY(x, y));
   }
 }
Example #21
0
  constructor(renderTarget0: RenderTarget, renderTarget1: RenderTarget) {
    // Internal UI state
    this._modelBounds = Rect.fromDimensions(2, 2);

    this._renderers = [
      new RenderableElementsRenderer(renderTarget0),
      new RenderableElementsRenderer(renderTarget1),
    ];
    this.renderParams = new RenderableElementsRendererParams();
    this._needsRedraw = false;

    // Right panel supports "unfolding" and "dual"
    this._viewModes = ["", "dual"];

    this._apex = Coords2d.fromXY(0.6, 0.6);
    this._source = TangentCoords2d.fromBaseAndOffset(
      Coords2d.fromXY(0.5, 0.3),
      OffsetCoords2d.fromDxDy(1, 0)
    );

    this.vForward = 0;
    this.vRight = 0;
    this.vAngle = 0;

    this.drawDistance = 30;
    this.skipOdd = false;
    this.decayParam = 100;
    this._showPath = true;
    //this._showUnfolding = true;
    this._unfoldingViewSize = 7.14;

    this.edgePaths = [
      // Just here for reference, anything less than (1, 1) is acute-only
      "RLRLRL", // (0, 0, 0)

      // Winding number 1 with no backtracking:
      // (<= 1 backtrack means all middle indices are 0)
      "RRRLRRRLLLRLLL", // Big central triangle (1, 0, 1)
      "RRRRRLRRRLLLLLRLLL", // Left child (2, 0, 1)
      "RRRRRLRRRRRLLLLLRLLLLL", // Center child (2, 0, 2)

      "RRRRRRRLRRRLLLLLLLRLLL", // Left grandchild (3, 0, 1)
      "RRRRRRRLRRRRRLLLLLLLRLLLLL", // (3, 0, 2)
      //"RRRRRRRLRRRRRRRLLLLLLLRLLLLLLL", // (3, 0, 3)

      //"RRRRRRRRRLRRRLLLLLLLLLRLLL", // (4, 0, 1)
      "RRRRRRRRRLRRRRRLLLLLLLLLRLLLLL", // (4, 0, 2)
      /*"RRRRRRRRRLRRRRRRRLLLLLLLLLRLLLLLLL", // (4, 0, 3)
      "RRRRRRRRRLRRRRRRRRRLLLLLLLLLRLLLLLLLLL", // (4, 0, 4)

      "RRRRRRRRRRRLRRRLLLLLLLLLLLRLLL", // (5, 0, 1)
      "RRRRRRRRRRRLRRRRRLLLLLLLLLLLRLLLLL", // (5, 0, 2)
      "RRRRRRRRRRRLRRRRRRRLLLLLLLLLLLRLLLLLLL", // (5, 0, 3)
      "RRRRRRRRRRRLRRRRRRRRRLLLLLLLLLLLRLLLLLLLLL", // (5, 0, 4)
      "RRRRRRRRRRRLRRRRRRRRRRRLLLLLLLLLLLRLLLLLLLLLLL", // (5, 0, 5)
      */
    /*  "RRRRRRRRRRRRRLRRRLLLLLLLLLLLLLRLLL", // (6, 0, 1)
      "RRRRRRRRRRRRRLRRRRRLLLLLLLLLLLLLRLLLLL", // (6, 0, 2)
      "RRRRRRRRRRRRRLRRRRRRRLLLLLLLLLLLLLRLLLLLLL", // (6, 0, 3)
      "RRRRRRRRRRRRRLRRRRRRRRRLLLLLLLLLLLLLRLLLLLLLLL", // (6, 0, 4)
      "RRRRRRRRRRRRRLRRRRRRRRRRRLLLLLLLLLLLLLRLLLLLLLLLLL", // (6, 0, 5)
      "RRRRRRRRRRRRRLRRRRRRRRRRRRRLLLLLLLLLLLLLRLLLLLLLLLLLLL", // (6, 0, 6)

      // Variant with one backtrack:
      "RRRRRLRLLRRLLLRLLL", // (2,0,1), [-3, -1, 1, -1, 2, 2]
      "RRRRRLRRRLLRRLLLRLLLLL", // (2,0,2), [-3, -2, 1, -1, 2, 3]
      "RRRRRRRLRLLRRLLLLLRLLL", // (3,0,1), [-4, -1, 1, -1, 3, 2]
      "RRRRRRRLRRRLLRRLLLLLRLLLLL", // (3,0,2)
      // (3,0,3) yields nothing
      "RRRRRRRRRLRLLRRLLLLLLLRLLL", // (4,0,1)
      "RRRRRRRRRLRRRLLRRLLLLLLLRLLLLL", // (4,0,2)
      // (4,0,3) yields nothing
      "RRRRRRRRRRRLRLLRRLLLLLLLLLRLLL", // (5,0,1)
      "RRRRRRRRRRRLRRRLLRRLLLLLLLLLRLLLLL", // (5,0,2)
      "RRRRRRRRRRRRRLRLLRRLLLLLLLLLLLRLLL", // (6,0,1)
      "RRRRRRRRRRRRRRRLRLLRRLLLLLLLLLLLLLRLLL", // (7,0,1)

      // Canonical winding number zero, acute only:
      //"RLRLRLLRLRLR",

      // Winding number zero, no mid-cycle backtrack
      "RRRLRLLLRLLRLLLRLRRR", // (1, 0, 0) [-4, -1, 2, 2, 2, -1]
      "RRRRRLRLLLLLRLLRLLLLLRLRRRRR", // (2, 0, 0)
      "RRRRRRRLRLLLLLLLRLLRLLLLLLLRLRRRRRRR", // (3, 0, 0)
      "RRRRRRRRRLRLLLLLLLLLRLLRLLLLLLLLLRLRRRRRRRRR", // (4, 0, 0)

      // Winding number 1, two backtracks variant:
      "RRLLRRRLRRRLLRRLLLRLLL", // (2, 0, 2)
      "RRRRLLRRRLRRRLLLLRRLLLRLLL", // (3, 0, 2)
      "RRRRLLRRRLRRRRRLLLLRRLLLRLLLLL", // (3, 0, 3)

      // Winding number 1, two backtracks:
      "RRLLRRRRRLRLLRRLLLLLRL", // (3, 1, 1)
      "RRLLRRRRRLRRRLLRRLLLLLRLLL", // (3, 1, 2)
      "RRLLRRRRRRRLRLLRRLLLLLLLRL", // (4, 1, 1)
      "RRRRLLRRRRRLRLLRRLLLLLLLRL", // (4, 1, 1)
      "RRRRLLRRRRRLRRRLLRRLLLLLLLRLLL", // (4, 1, 2)
      "RRRRLLRRRRRLRRRLLLLRRLLLLLRLLL", // (4, 1, 2)
      "RRRRLLRRRRRLRRRLLLLLLRRLLLRLLL", // (4, 1, 2)
      "RRRRRRLLRRRLRRRLLLLLLRRLLLRLLL", // (4, 1, 2)
      "RRLLRRRRRRRRRLRLLRRLLLLLLLLLRL", // (5, 1, 1)
      "RRRRLLRRRRRRRLRLLRRLLLLLLLLLRL", // (5, 1, 1)
      "RRRRLLRRRRRRRLRLLLLRRLLLLLLLRL", // (5, 1, 1)
      "RRRRLLRRRRRRRLRRRLLLLRRLLLLLLLRLLL", // (5, 1, 2)
      "RRRRLLRRRRRRRLRRRLLLLLLRRLLLLLRLLL", // (5, 1, 2)
      "RRRRRRLLRRRRRLRRRLLLLLLRRLLLLLRLLL", // (5, 1, 2)
      "RRRRRRLLRRRRRLRRRLLLLLLLLRRLLLRLLL", // (5, 1, 2)
      "RRLLRRRRRRRRRRRLRLLRRLLLLLLLLLLLRL", // (6, 1, 1)
      "RRRRLLRRRRRRRRRLRLLRRLLLLLLLLLLLRL", // (6, 1, 1)
      "RRRRLLRRRRRRRRRLRLLLLRRLLLLLLLLLRL", // (6, 1, 1)
      "RRRRRRLLRRRRRRRLRLLLLRRLLLLLLLLLRL", // (6, 1, 1)
      "RRLLRRRRRRRRRRRRRLRLLRRLLLLLLLLLLLLLRL", // (7, 1, 1)
      "RRRRLLRRRRRRRRRRRLRLLLLRRLLLLLLLLLLLRL", // (7, 1, 1)
      "RRLLRRRRRRRRRRRRRRRLRLLRRLLLLLLLLLLLLLLLRL", // (8, 1, 1)
      "RRRRLLRRRRRRRRRRRRRLRLLLLRRLLLLLLLLLLLLLRL", // (8, 1, 1)
      "RRLLRRRRRRRRRRRRRRRRRLRLLRRLLLLLLLLLLLLLLLLLRL", // (9, 1, 1)
      "RRRRLLRRRRRRRRRRRRRRRLRLLLLRRLLLLLLLLLLLLLLLRL", // (9, 1, 1)

      // Winding number 0
      "RLRLLRLRRRRLRLRLLRLLLLRLLRLRLRRR",

      // Begin unclassified
      "LRLLLLLRRLLRLRRRRRLLLRLRLRRR",
      "RRRRRRLLRRRRLRLLLLLLLLLRRLLLLRLRRR",
      "LRLLLLLLLLLRRRLRRRRRRRLLRRRRLLRRRRRRRLRRRLLLLLLLLLRL",
      "LLRRLRLLLLRLRRLLRRRLRRLRLRLLLRRLLRRLLRLRRR",
      "LRLLLLLRRRRLLLLRRRRRLRRRRRLLLLRRRRLLLL"
      // End unclassified
      */
    ];
    this.originalEdgePaths = this.edgePaths.map((x) => x);
    this.highlightCount = 1;
  }