一日一练:有效的回旋镖

给定一个数组 points ,其中 points[i] = [xi, yi] 表示 X-Y 平面上的一个点,如果这些点构成一个 回旋镖 则返回 true 。回旋镖 定义为一组三个点,这些点 各不相同 且 不在一条直线上 。

这是一道数学题。

x,y 坐标

  1. 首先排除三点相同的情况
  2. 然后判断是否可以连成一条线:将 其中一点平移到原点,其他两个点在xy轴上移动相同的距离,然后计算这两个点与原点形成的角度是否相同(区分正负)

如下 [[0, 1], [2, 0], [2, 2]] 三点

image.png

移动[0, 1]到原点[0, 0],则[2, 0]移动到了[2, -1][2, 2]移到了[2, 1],计算这两个点与x轴的夹角分别为-45°45°。夹角不同,所以不在一条直接上。

image.png

代码实现:

function isBoomerang(points: number[][]): boolean {
  const x1 = points[0][0],
    y1 = points[0][1],
    x2 = points[1][0],
    y2 = points[1][1],
    x3 = points[2][0],
    y3 = points[2][1]
  const set = new Set([`${x1}.${y1}`, `${x2}.${y2}`, `${x3}.${y3}`])
  // 各不相同
  if (set.size !== 3) return false
  // 不在一条直线上
  let movedX2 = x2 - x1,
    movedy2 = y2 - y1
  let movedx3 = x3 - x1,
    movedy3 = y3 - y1
  if (getRate(movedX2, movedy2) === getRate(movedx3, movedy3)) return false
  return true
}

// 求与x轴的夹角
function getRate(x: number, y: number) {
  let xp = x ** 2
  let yp = y ** 2
  return ((x * y > 0 ? 1 : -1) * xp) / (xp + yp)
}

向量叉乘

除了x,y垂直坐标,还可以用三点构成两个向量,然后根据平行的性质,叉乘为0

function isBoomerang_v2(points: number[][]): boolean {
  const v1 = [points[1][0] - points[0][0], points[1][1] - points[0][1]]
  const v2 = [points[2][0] - points[0][0], points[2][1] - points[0][1]]
  return v1[0] * v2[1] - v1[1] * v2[0] != 0
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值