All files / src/objects Circle.js

0% Statements 0/57
0% Branches 0/24
0% Functions 0/10
0% Lines 0/55

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137                                                                                                                                                                                                                                                                                 
import {
  translate2D,
  verticalProjectionOnPlane,
  get3DDistanceBetweenPoints,
  getDistanceBetweenPoints
} from '../geometry'
import { v4 as uuidv4 } from 'uuid'
import { Point } from './Point'
import {
  addVector,
  multiplyVector,
  substractVector,
  vectorLength,
  crossProduct,
  dotProduct,
  normalizeVector
} from '../vector'
 
export class Circle {
  constructor(center, radius, layer) {
    this.id = uuidv4()
    this.type = 'circle'
    this.version = 0
    this.center = center
    this.radius = radius
    this.layer = layer
    this.visible = true
  }
 
  clone() {
    const circle = new Circle(
      new Point(this.point.x, this.point.y),
      this.radius,
      this.layer
    )
    circle.id = uuidv4()
    return circle
  }
  getIntersections(object) {
    const intersections = []
    if (!object) return
    if (object.type == 'point') {
      if (get3DDistanceBetweenPoints(object, this.center) == this.radius) {
        intersections.push({ ...object })
      }
    } else if (object.type == 'line') {
      let P = object.getProjectedPoint(this.center)
      let distance = get3DDistanceBetweenPoints(P, this.center)
      if (distance <= this.radius) {
        let A = addVector(
          P,
          multiplyVector(
            Math.sqrt(Math.pow(this.radius, 2) - Math.pow(distance, 2)),
            object.getDirectionVector()
          )
        )
        let B = addVector(
          P,
          multiplyVector(
            -Math.sqrt(Math.pow(this.radius, 2) - Math.pow(distance, 2)),
            object.getDirectionVector()
          )
        )
        intersections.push({ ...A })
        intersections.push({ ...B })
      }
    }
    return intersections
  }
  getPxDistanceTo(point, canvasContext) {
    const toCanvasRef = canvasContext.toCanvasRef
    let pxCenter = toCanvasRef(this.center)
    let pxRadius = this.radius / canvasContext.mmPerPx
    if (this.normalVector) {
      point.z = verticalProjectionOnPlane(
        point,
        this.normalVector,
        this.center
      ).z
    } else {
      point.z = this.center.z
    }
    return Math.abs(get3DDistanceBetweenPoints(point, pxCenter) - pxRadius)
  }
  getDistanceToPoint(point) {
    return get3DDistanceBetweenPoints(point, this.getProjectedPoint(point))
  }
  getHorizontalDistanceToPoint(point) {
    return getDistanceBetweenPoints(
      point,
      this.getVerticalProjectedPoint(point)
    )
  }
  isInPlane(plane) {
    if (!plane) return false
    const { point, normalVector } = plane
    const circleNormalVector = this.normalVector || { x: 0, y: 0, z: 1 }
    if (vectorLength(crossProduct(circleNormalVector, normalVector)) > 0.1)
      return false
    if (
      dotProduct(
        normalizeVector(substractVector(point, this.center)),
        normalVector
      ) > 0.1
    )
      return false
    return true
  }
  getProjectedPoint(point) {
    if (this.normalVector) {
      point.z = verticalProjectionOnPlane(
        point,
        this.normalVector,
        this.center
      ).z
    } else {
      point.z = this.center.z
    }
    let distance = get3DDistanceBetweenPoints(point, this.center)
    if (distance == 0) {
      console.error("can't project center to cercle", this)
      return null
    }
    let x = this.center.x + (point.x - this.center.x) * (this.radius / distance)
    let y = this.center.y + (point.y - this.center.y) * (this.radius / distance)
    let z = this.center.z + (point.z - this.center.z) * (this.radius / distance)
    let P = new Point(x, y, z, this.layer)
    return P
  }
  getVerticalProjectedPoint(point) {
    return this.getProjectedPoint(point)
  }
  translate(vectorInMm) {
    this.center = translate2D(this.center, vectorInMm)
  }
}