我发现使用
angle <- (acos(sum(a*b) / (sqrt(sum(a * a)) * sqrt(sum(b * b)))))
是在R中两个向量a
和b
之间形成角度的最常见方法。
不幸的是,我一直在某些似乎彼此重叠或彼此之间具有大约180度角的矢量上出错。
例如:
a <- c(-7.6942088429381328e-01, 2.4999999999999989e-01)
b <- c(-5.4146791834239578e+08, 1.7593359143824694e+08)
不起作用。
我在用其他方法计算角度时也遇到类似的问题。
答案 0 :(得分:2)
我会使用向量运算。
让我们定义一个适当的函数// Import express
let express = require('express');
// Import Body parser
let bodyParser = require('body-parser');
// Import Mongoose
let mongoose = require('mongoose');
// Initialize the app
let app = express();
// Import routes
let apiRoutes = require("./api-routes");
// Configure bodyparser to handle post requests
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json());
// Connect to Mongoose and set connection variable
mongoose.connect('mongodb://XXXX:XXXX@cluster0-shard-00-00-ov74c.mongodb.net:27017,cluster0-shard-00-01-ov74c.mongodb.net:27017,cluster0-shard-00-02-ov74c.mongodb.net:27017/test?ssl=true&replicaSet=Cluster0-shard-0&authSource=admin&retryWrites=true&w=majority', {useNewUrlParser: true})
.then(()=>console.log("DB server connect"))
.catch(e => console.log("DB error", e));
var db = mongoose.connection;
// Added check for DB connection
if(!db)
console.log("Error connecting db")
else
console.log("Db connected successfully")
// Setup server port
var port = process.env.PORT || 8080;
// Send message for default URL
app.get('/', (req, res) => res.send('Hello World with Express'));
// Use Api routes in the App
app.use('/api', apiRoutes);
// Launch app to listen to specified port
app.listen(port, function () {
console.log("Running RestHub on port " + port);
});
,该函数以两个向量angle
和x1
x2
请注意,我们进行了数值稳定性检查,以确保对于接近0的角度,我们得到数值结果(而不是angle <- function(x1, x2, tol = 1e-6) {
cost <- as.numeric((x1 %*% x2) / (sqrt(x1 %*% x1) * sqrt(x2 %*% x2)))
if (abs(cost - 1) < tol) return(0) else return(acos(cost))
}
)。
然后计算两个矢量之间的角度(以弧度为单位),例如
NA
我们做
x1 <- c(1, 1)
x2 <- c(0.5, 2)
就您而言,
angle(x1, x2)
#[1] 0.5404195
请注意,这也适用于高维向量,例如
angle(a, b)
#[1] 0