DropCircle.ts
1 import _ from 'lodash' 2 import { RoaringBitmap32, SerializationFormat } from 'roaring' 3 import { CircleGeometryParameters, GeometryType, IGeometryGenerator } from './Interfaces' 4 5 /* 6 Computing polygon points: 7 - compute circumference of circle 8 - divide by 3 to get amount of points you get along circle line 9 10 Example: 11 - radius of 20 12 - circumference is 125.6637 13 - division by 3 gets you Math.floor(result) of 41 14 */ 15 16 /* 17 Implementation left out for future testing/reference. 18 */ 19 function unwrap( value: number ) : any { 20 let x = 0x0000FFFF & value 21 let y = value >> 16 22 23 return { x, y } 24 } 25 26 export class DropCircle implements IGeometryGenerator { 27 name: string 28 minRadius: number 29 maxRadius: number 30 radiusIncrement: number 31 data: RoaringBitmap32 = new RoaringBitmap32() 32 distanceBetweenPoints: number 33 34 constructor( name: string, minRadius: number, maxRadius: number, radiusIncrement: number, pointDistance : number = 5 ) { 35 this.name = name 36 this.minRadius = minRadius 37 this.maxRadius = maxRadius 38 this.radiusIncrement = radiusIncrement 39 this.distanceBetweenPoints = pointDistance 40 41 if ( this.minRadius === this.maxRadius ) { 42 this.data.addMany( this.createCirclePoints( this.minRadius, this.maxRadius, this.maxRadius ) ) 43 return 44 } 45 46 for ( let radius = this.minRadius; radius <= this.maxRadius; radius = radius + this.radiusIncrement ) { 47 this.data.addMany( this.createCirclePoints( radius, this.maxRadius, this.maxRadius ) ) 48 } 49 } 50 51 private createCirclePoints( radius: number, centerX: number, centerY: number ): Array<number> { 52 let circumference = Math.PI * 2 * radius 53 let amount = Math.floor( circumference / this.distanceBetweenPoints ) 54 55 return _.times( amount, ( index: number ): number => { 56 let ratio = ( index * Math.PI * 2 ) / amount 57 let x = centerX + Math.round( radius * Math.cos( ratio ) ) 58 let y = centerY + Math.round( radius * Math.sin( ratio ) ) 59 60 return x + ( y << 16 ) 61 } ) 62 } 63 64 generatePoints() : Buffer { 65 // @ts-ignore 66 return this.data.serialize( SerializationFormat.croaring ) 67 } 68 69 getParameters() : CircleGeometryParameters { 70 return { 71 maxRadius: this.maxRadius, 72 minRadius: this.minRadius, 73 stepIncrement: this.radiusIncrement, 74 } 75 } 76 77 getName(): string { 78 return this.name 79 } 80 81 getSize(): number { 82 return this.data.size 83 } 84 85 getType(): GeometryType { 86 return GeometryType.PointCircle 87 } 88 }