golang 三维向量相关操作

package vector

import (
    "math"
    "fmt"
)// 三维向量:(x,y,z)
type Vector3 struct {
    X float64    `json:"x"`
    Y float64    `json:"y"`
    Z float64    `json:"z"`
}

func (this *Vector3)Equal(v Vector3) bool {
    return this.X == v.X && this.Y == v.Y && this.Z == v.Z
}

// 三维向量:设值
func (this *Vector3)Set(x, y, z float64) {
    this.X = x
    this.Y = y
    this.Z = z
}
// 三维向量:拷贝
func (this *Vector3)Clone() Vector3 {
    return NewVector3(this.X, this.Y, this.Z)
}

// 三维向量:加上
// this = this + v
func (this *Vector3)Add(v Vector3) {
    this.X += v.X
    this.Y += v.Y
    this.Z += v.Z
}

// 三维向量:减去
// this = this - v
func (this *Vector3)Sub(v Vector3) {
    this.X -= v.X
    this.Y -= v.Y
    this.Z -= v.Z
}

// 三维向量:数乘
func (this *Vector3)Multiply(scalar float64) {
    this.X *= scalar
    this.Y *= scalar
    this.Z *= scalar
}

func (this *Vector3)Divide(scalar float64) {
    if scalar == 0 {
        panic("分母不能为零!")
    }
    this.Multiply(1 / scalar)
}

// 三维向量:点积
func (this *Vector3)Dot(v Vector3) float64 {
    return this.X * v.X + this.Y * v.Y + this.Z * v.Z
}

// 三维向量:叉积
func (this *Vector3)Cross(v Vector3) {
    x, y, z := this.X, this.Y, this.Z
    this.X = y * v.Z - z * v.Y;
    this.Y = z * v.X - x * v.Z;
    this.Z = x * v.Y - y * v.X;
}

// 三维向量:长度
func (this *Vector3)Length() float64 {
    return math.Sqrt(this.X * this.X + this.Y * this.Y + this.Z * this.Z)
}

// 三维向量:长度平方
func (this *Vector3)LengthSq() float64 {
    return this.X * this.X + this.Y * this.Y + this.Z * this.Z
}

// 三维向量:单位化
func (this *Vector3)Normalize() {
    this.Divide(this.Length())
}

// 返回:新向量
func NewVector3(x, y, z float64) Vector3 {
    return Vector3{X:x, Y:y, Z:z}
}

// 返回:零向量(0,0,0)
func Zero3() Vector3 {
    return Vector3{X:0, Y:0, Z:0}
}
// X 轴 单位向量
func XAxis3() Vector3 {
    return Vector3{X:1, Y:0, Z:0}
}
// Y 轴 单位向量
func YAxis3() Vector3 {
    return Vector3{X:0, Y:1, Z:0}
}

// Z 轴 单位向量
func ZAxis3() Vector3 {
    return Vector3{X:0, Y:0, Z:1}
}
func XYAxis3() Vector3 {
    return Vector3{X:1, Y:1, Z:0}
}
func XZAxis3() Vector3 {
    return Vector3{X:1, Y:0, Z:1}
}
func YZAxis3() Vector3 {
    return Vector3{X:0, Y:1, Z:1}
}
func XYZAxis3() Vector3 {
    return Vector3{X:1, Y:1, Z:1}
}

// 返回:a + b 向量
func Add3(a, b Vector3) Vector3 {
    return Vector3{X:a.X + b.X, Y:a.Y + b.Y, Z:a.Z + b.Z}
}

// 返回:a - b 向量
func Sub3(a, b Vector3) Vector3 {
    return Vector3{X:a.X - b.X, Y:a.Y - b.Y, Z:a.Z - b.Z}
}

// 返回:a X b 向量 (X 叉乘)
func Cross3(a, b Vector3) Vector3 {
    return Vector3{X:a.Y * b.Z - a.Z * b.Y, Y:a.Z * b.X - a.X * b.Z, Z:a.X * b.Y - a.Y * b.X}
}

func AddArray3(vs []Vector3, dv Vector3) []Vector3 {
    for i,_ := range vs {
        vs[i].Add(dv)
    }
    return vs
}

func Multiply3(v Vector3,scalars []float64) []Vector3 {
    vs := []Vector3{}
    for _,value := range scalars {
        vector := v.Clone()
        vector.Multiply(value)
        vs = append(vs, vector)
    }
    return vs
}

// 返回:单位化向量
func Normalize3(a Vector3) Vector3 {
    b := a.Clone()
    b.Normalize()
    return b
}//求两点间距离
func GetDistance(a Vector3,b Vector3) float64{
    return math.Sqrt(math.Pow(a.X - b.X, 2) + math.Pow(a.Y - b.Y, 2) + math.Pow(a.Z - b.Z, 2))
}

原文地址:https://www.cnblogs.com/zheng123/p/9648868.html

时间: 2024-10-11 22:33:25

golang 三维向量相关操作的相关文章

R语言入门心得(3) -- 向量相关

向量定义 R在实际应用中比较常用的一个对象就是向量(Vector).向量的创建格式为 向量名 = c(x1,x2,x3,…..)  或  向量名 <- c(x1,x2,x3,…..) 或  c(x1,x2,x3,…..) -> 向量名 或  Assign("向量名", c(x1,x2,x3,…..)),c()为向量赋值函数,c()可以有任意多个参数,而起返回值则是一个把这些参数首尾相连形成的向量.你可以在命令行中输入?c或者help(c)来查看函数的详细信息.例如我们要创建

Scala学习(三)----数组相关操作

数组相关操作 摘要: 本篇主要学习如何在Scala中操作数组.Java和C++程序员通常会选用数组或近似的结构(比如数组列表或向量)来收集一组元素.在Scala中,我们的选择更多,不过现在我们先假定不关心其他选择,而只是想马上开始用数组.本篇的要点包括: 1. 若长度固定则使用Array,若长度可能有变化则使用ArrayBuffer 2. 提供初始值时不要使用new 3. 用()来访问元素 4. 用for (elem<-arr)来遍历元素 5. 用for (elem<-arr if…)…yie

php对二维数组进行相关操作(排序、转换、去空白等)

php对二维数组进行相关操作(排序.转换.去空白等) 投稿:lijiao 字体:[增加 减小] 类型:转载 时间:2015-11-04 这篇文章主要介绍了php对二维数组进行相关操作,包括php对二维数组排序.转换.去空白,以及去重复值等,感兴趣的小伙伴们可以参考一下 技巧提示: ? 1 2 3 4 5 6 7 8 9 array_keys($array) //返回所有键名   array_values($array) //返回所有键值    $result=array_reverse($inp

Scala详解---------数组相关操作

Scala中提供了一种数据结构-数组,其中存储相同类型的元素的固定大小的连续集合.数组用于存储数据的集合,但它往往是更加有用认为数组作为相同类型的变量的集合. 取替声明单个变量,如number0, number1, ..., 和number99,声明一个数组变量,如号码和使用numbers[0],numbers[1],...,numbers[99]表示单个变量.本教程介绍了如何声明数组变量,创建数组和使用索引的过程变量数组.数组的第一个元素的索引是数字0和最后一个元素的索引为元素的总数减去1.

关于golang中IO相关的Buffer类浅析

io重要的接口 在介绍buffer之前,先来认识两个重要的接口,如下边所示: type Reader interface { Read(p []byte) (n int, err error) } type Writer interface { Write(p []byte) (n int, err error) } 上边两个接口在golang sdk安装目录src/io/io.go中定义.后边凡是涉及到io相关操作的,基本上都实现了这两个接口,如: 1. package bufio 中的Rea

(1)spark核心RDD的概念解析、创建、以及相关操作

spark核心之RDD 什么是RDD RDD指的是弹性分布式数据集(Resilient Distributed Dataset),它是spark计算的核心.尽管后面我们会使用DataFrame.Dataset进行编程,但是它们的底层依旧是依赖于RDD的.我们来解释一下RDD(Resilient Distributed Dataset)的这几个单词含义. 弹性:在计算上具有容错性,spark是一个计算框架,如果某一个节点挂了,可以自动进行计算之间血缘关系的跟踪 分布式:很好理解,hdfs上数据是跨

二叉树的相关操作

#include<stdio.h> #include<malloc.h> #define MAXSIZE 20 typedef char TEelemtype; typedef struct BiTNode{ TEelemtype data; struct BiTNode *lchild,*rchild; }BiTNode,*BiTree; //队列的方式 typedef struct queueelem { BiTNode* b[MAXSIZE]; int front,rear;

(二十四)linux新定时器:timefd及相关操作函数

timerfd是Linux为用户程序提供的一个定时器接口.这个接口基于文件描述符,通过文件描述符的可读事件进行超时通知,所以能够被用于select/poll的应用场景. 一,相关操作函数 #include <sys/timerfd.h> int timerfd_create(int clockid, int flags); int timerfd_settime(int fd, int flags, const struct itimerspec *new_value, struct itim

二叉树各种相关操作(建立二叉树、前序、中序、后序、求二叉树的深度、查找二叉树节点,层次遍历二叉树等)(C语言版)

将二叉树相关的操作集中在一个实例里,有助于理解有关二叉树的相关操作: 1.定义树的结构体: 1 typedef struct TreeNode{ 2 int data; 3 struct TreeNode *left; 4 struct TreeNode *right; 5 }TreeNode; 2.创建根节点: 1 TreeNode *creatRoot(){ 2 TreeNode * root =(TreeNode *)malloc(sizeof(TreeNode)); 3 if(NULL=