<commit_before>import THREE from 'three.js';
import times from 'lodash/utility/times';

const lineMaterial = new THREE.LineBasicMaterial({
  blending: THREE.AdditiveBlending,
  color: '#f43',
  linewidth: 16,
  opacity: 0.25,
  side: THREE.DoubleSide,
  transparent: true
});

export class LineTrail extends THREE.Line {
  constructor( count = 64 ) {
    const geometry = new THREE.BufferGeometry();
    const vertices = new Float32Array( 3 * count );
    const attribute = new THREE.BufferAttribute( vertices, 3 );
    geometry.addAttribute( 'position', attribute );

    super( geometry, lineMaterial );

    // Offset from target.
    this.offset = new THREE.Vector3();

    // Circular array of previous positions.
    this.positions = times( count, () => new THREE.Vector3() );

    // Current index of position array start.
    this.start = 0;

    this.frustumCulled = false;
  }

  track( target ) {
    const { position } = this.geometry.attributes;
    let index = 0;

    for ( let i = this.start; i < this.positions.length; i++ ) {
      this.positions[i].toArray( position.array, 3 * index );
      index++;
    }

    for ( let i = 0; i < this.start; i++ ) {
      this.positions[i].toArray( position.array, 3 * index );
      index++;
    }

    this.positions[ this.start ].copy( this.offset )
      .applyQuaternion( target.quaternion )
      .add( target.position );

    this.start = ( this.start + 1 ) % this.positions.length;

    position.needsUpdate = true;
  }
}


const size = 256;

const canvas = document.createElement( 'canvas' );
const ctx = canvas.getContext( '2d' );

canvas.width = size;
canvas.height = size;<commit_msg>Simplify LineTrail geometry generation method.<commit_after>import THREE from 'three.js';
import times from 'lodash/utility/times';

const lineMaterial = new THREE.LineBasicMaterial({
  blending: THREE.AdditiveBlending,
  color: '#f43',
  linewidth: 16,
  opacity: 0.25,
  side: THREE.DoubleSide,
  transparent: true
});

export class LineTrail extends THREE.Line {
  constructor( count = 64 ) {
    const geometry = new THREE.BufferGeometry();
    const vertices = new Float32Array( 3 * count );
    const attribute = new THREE.BufferAttribute( vertices, 3 );
    geometry.addAttribute( 'position', attribute );

    super( geometry, lineMaterial );

    // Offset from target.
    this.offset = new THREE.Vector3();

    // Circular array of previous positions.
    this.positions = times( count, () => new THREE.Vector3() );

    // Current index of position array start.
    this.start = 0;

    this.frustumCulled = false;
  }

  track( target ) {
    this.positions[ this.start ].copy( this.offset )
      .applyQuaternion( target.quaternion )
      .add( target.position );

    this.start = ( this.start + 1 ) % this.positions.length;
  }

  generate() {
    const { position } = this.geometry.attributes;

    for ( let i = 0; i < this.positions.length; i++ ) {
      const index = ( i + this.start ) % this.positions.length;
      this.positions[ index ].toArray( position.array, 3 * i );
    }

    position.needsUpdate = true;
  }
}


const size = 256;

const canvas = document.createElement( 'canvas' );
const ctx = canvas.getContext( '2d' );

canvas.width = size;
canvas.height = size;
{'fraction_non_alphanumeric': 0.12976629766297662, 'fraction_numerical': 0.014760147601476014, 'mean_word_length': 3.030978934324659, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7271413', 'n_tokens_mistral': 1074, 'n_tokens_neox': 975, 'n_words': 277}