/* Copyright 2021 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================
*/

package org.tensorflow.lite.examples.poseestimation.data

import android.graphics.PointF
import kotlin.math.acos
import kotlin.math.atan2
import kotlin.math.sqrt

data class KeyPoint(
    // bodyPart 表示该关键点对应的人体部位，是一个 BodyPart 枚举类型
    val bodyPart: BodyPart,

    // coordinate 表示该关键点的坐标位置，是一个 PointF 对象，包含了 x 和 y 坐标
    var coordinate: PointF,

    // score 表示该关键点的置信度分数，值越高表示模型对该关键点预测的准确性越高
    val score: Float
){

    // 函数1: 计算两点连线与竖直方向和水平方向的夹角
    fun abtPoints(other: KeyPoint): Pair<Float, Float> {
        val dx = other.coordinate.x - this.coordinate.x
        val dy = other.coordinate.y - this.coordinate.y

        // 计算连线与水平方向的夹角（atan2返回的是弧度，转成角度）
        val angleX = Math.toDegrees(atan2(dy.toDouble(), dx.toDouble())).toFloat()

        // 计算连线与竖直方向的夹角
        val angleY = Math.toDegrees(atan2(dx.toDouble(), dy.toDouble())).toFloat()

        return Pair(angleX, angleY)
    }

    // 函数2: 计算角ABC
    fun abttPoints(A: KeyPoint, B: KeyPoint, C: KeyPoint): Float {
        // 计算向量BA和BC的坐标
        val BAx = A.coordinate.x - B.coordinate.x
        val BAy = A.coordinate.y - B.coordinate.y
        val BCx = C.coordinate.x - B.coordinate.x
        val BCy = C.coordinate.y - B.coordinate.y

        // 计算BA和BC的点积
        val dotProduct = BAx * BCx + BAy * BCy

        // 计算BA和BC的模长
        val magBA = sqrt(BAx * BAx + BAy * BAy)
        val magBC = sqrt(BCx * BCx + BCy * BCy)

        // 计算夹角的cos值
        val cosAngle = dotProduct / (magBA * magBC)

        // 计算夹角的角度（弧度转角度）
        val angle = Math.toDegrees(acos(cosAngle.toDouble())).toFloat()

        return angle
    }
}
