• 二维平面中二维向量的叉乘 得到的向量,x、y方向上的分量必定为0,
    所以可以用z的值判断一个向量在另一个向量的左侧还是右侧。
  • 推导(其实这个是二维上的定义,先用二维的推出来的三维,我用三维反过来理解二维。。):
    由于z1 = z2 = 0,那么 axb = k(x1y2 - y1x2)
    只存在z轴上的分量。
//没用的代码增加了
#define _VecTypeName double
class Solution {public:
// -------手写通用矩阵运算库----------// 点乘template <typename T>T dot(vector<T>& vec2_1 ,vector<T>& vec2_2){return vec2_1[0] * vec2_2[0] + vec2_1[1] * vec2_2[1];}// 叉乘,这里只要它z轴上的分量template <typename T>T cross(vector<T>& vec2_1 ,vector<T>& vec2_2){return vec2_1[0] * vec2_2[1] - vec2_1[1] * vec2_2[0];}// 归一化void normalize(vector<_VecTypeName>& vec2){if (vec2[0] == 0 || vec2[1] == 0)return;_VecTypeName sqx = vec2[0] * vec2[0];_VecTypeName sqy = vec2[1] * vec2[1];//cout << vec2[0] << " *in* " << vec2[1];vec2[0] = sqrt(sqx / (sqx + sqy)) * (vec2[0] / abs(vec2[0]));vec2[1] = sqrt(sqy / (sqx + sqy)) * (vec2[1] / abs(vec2[1]));//cout << vec2[0] << " *out* " << vec2[1];}// 构造 point1 指向 point2 的二维单位向量template <typename T>void makeVec2(vector<T>& vec2, vector<int>& point1, vector<int>& point2){vec2[0] = T(point2[0] - point1[0]);vec2[1] = T(point2[1] - point1[1]);//normalize<T>(vec2);}// 向量叠加void addVec(vector<_VecTypeName>& vec2,vector<_VecTypeName>& vec2_1 ,vector<_VecTypeName>& vec2_2){vec2[0] = vec2_1[0] + vec2_2[0];vec2[1] = vec2_1[1] + vec2_2[1];}// 获取xmin的点void getXMinPoint(vector<int>& point,vector<vector<int>>& trees){int xmin = INT_MAX;for (unsigned int i = 0; i < trees.size(); ++i){int x = trees[i][0];if (xmin > x){xmin = x;point[0] = trees[i][0];point[1] = trees[i][1];}}}// 获取以x+轴为方向的向量template <typename T>void getPolarCoordinates(vector<T>& vec2){vec2[0] = 1;vec2[1] = 0;}// 判断两个位置或向量template <typename T>bool equalVec2(T& point1, T& point2){return point1[0] == point2[0] and point1[1] == point2[1];}// template <typename T>int setLevelFromDotAndCross(T& dotdata, T& crossdata){int leveldata = 0;if (crossdata < 0)leveldata = 5;else if (crossdata == 0 && dotdata > 0)leveldata = 4;else if (crossdata > 0)leveldata = 3;else if (crossdata == 0 && dotdata <= 0)leveldata = 2;return leveldata;}// 比较逆时针度数template <typename T>bool compareDotAndCross(T& dotdata1, T& crossdata1, T& dotdata2, T& crossdata2, T& ori_dotdata1, T& ori_dotdata2){/* 在逆时针上判断,cross < 0 的最大 (内部比较 点积越小逆时针角度越大),其次是 cross == 0 && dotdata > 0 的,再然后是 cross < 0 的 (内部比较 点积越大逆时针角度越大),再然后是 cross == 0 && dotdata <= 0 的*/int leveldata1 = setLevelFromDotAndCross<T>(dotdata1,crossdata1);int leveldata2 = setLevelFromDotAndCross<T>(dotdata2,crossdata2);// 叉积异号 直接得出结果if (leveldata1 != leveldata2)return leveldata1 > leveldata2;// 叉积同号 y-轴方向 点积越小逆时针角度越大if (leveldata1 == 5)return dotdata1 < dotdata2;// 同向要距离近的if (leveldata1 == 4)return ori_dotdata1 < ori_dotdata2;// 反向要距离近的if (leveldata1 == 2)return ori_dotdata1 > ori_dotdata2;// 叉积同号 y+轴方向 点积越小逆时针角度越小return dotdata1 > dotdata2;}// -------手写通用矩阵运算库----------// 寻找凸多边形 可以肯定 xmin xmax ymin ymax的点 在凸包上// 那么先用Jarvis算法,取xminvector<vector<int>> outerTrees(vector<vector<int>>& trees) {// 至少有三个点才能构成两个向量if (trees.size() <= 2) return trees;vector<vector<int>> cp_tree;for (unsigned int i = 0; i < trees.size(); ++i){vector<int> cp_data(2,0);cp_data[0] = trees[i][0];cp_data[1] = trees[i][1];cp_tree.push_back(cp_data);}vector<vector<int>> res;// 最开始的法向量,[1,0],之后每得到一个点法向量变化到上一个向量vector<_VecTypeName> axis_x(2,0);getPolarCoordinates<_VecTypeName>(axis_x);vector<int> point(2,0);getXMinPoint(point,trees);res.push_back(point);while(!(res.size() > 1 and equalVec2<vector<int>>(*(res.end() - 1),*(res.begin())))){// 最弱情况指向贴着x-轴的左上角角度_VecTypeName crossdata1 = 1;_VecTypeName dotdata1 = -999;// ori用来记录原始长度,算最近的点_VecTypeName ori_dotdata1 = 0;vector<int> pi(2,0);int index = -1;for (unsigned int i = 0; i < trees.size(); ++i){// 因为本算法每次找到最优解没有回溯,所以用完的直接扔掉不再参与运算。if (equalVec2<vector<int>>(*(res.end() - 1),trees[i])){continue;}vector<_VecTypeName> vecp(2,0);makeVec2<_VecTypeName>(vecp,*(res.end() - 1),trees[i]);_VecTypeName ori_dotdata2 = dot<_VecTypeName>(axis_x,vecp);normalize(vecp);_VecTypeName crossdata2 = cross<_VecTypeName>(axis_x,vecp);_VecTypeName dotdata2 = dot<_VecTypeName>(axis_x,vecp);if (!compareDotAndCross<_VecTypeName>(dotdata1,crossdata1,dotdata2,crossdata2,ori_dotdata1,ori_dotdata2)){// if (trees[i][0] == 4 and trees[i][1] == 0 and res.size() == 4)// {//     cout << "start" << endl << dotdata1 << " " << crossdata1 << endl << dotdata2 << " " << crossdata2 << endl << "end" << endl;//     cout << "curpos [ " << axis_x[0] << axis_x[1] << " ] thispos [ " << vecp[0] << vecp[1] << " ]" << endl;// }// else{//     cout << "lastpos [ " << vecp[0] << vecp[1] << " ]" << endl;// }crossdata1 = crossdata2;dotdata1 = dotdata2;ori_dotdata1 = ori_dotdata2;pi[0] = trees[i][0];pi[1] = trees[i][1];index = i;}}if (index >= 0){makeVec2<_VecTypeName>(axis_x,*(res.end() - 1),pi);normalize(axis_x);res.push_back(pi);cout << index << " " << trees.size() << endl;trees.erase(trees.begin() + index);}else{return cp_tree;}}res.erase(res.end()-1);return res;}
};/*
取[1,1] [m,n]遍历其他顶点,
先用叉乘确定法向量的方向,决定在左边还是在右边,
再用点积确定夹角,重合是1,逆向是-1,负数角度大,正数角度小
*/

二维平面中二维向量的叉乘 得到的向量,x、y方向上的分量必定为0相关推荐

  1. 现在,我们用大炮来打蚊子:蚊子分布在一个M×N格的二维平面上,每只蚊子占据一格。向该平面的任意位置发射炮弹,炮弹的杀伤范围如下示意:

    目录 输入格式: 输出格式: 输入样例: 输出样例: 正确答案: 现在,我们用大炮来打蚊子:蚊子分布在一个M×N格的二维平面上,每只蚊子占据一格.向该平面的任意位置发射炮弹,炮弹的杀伤范围如下示意: ...

  2. 二维向量的叉积是标量还是向量?

    二维向量的叉积是标量还是向量? 今天学习了一下<计算几何>,里面讲了一下关于判断一个点是否在某个三角形内的问题(在二维平面上).其中有一个算法是"同向法",主要是用叉积 ...

  3. matlab 二维样条插值函数,matlab中二维插值函数interp2的使用详解

    下面是一段产生log-normal分布的代码,以此进行说明. clear all; clc; for t=1:100 Traffic(t) =curve(t); end MaxTraffic = ma ...

  4. 二维树状数组 ----2021广东省赛 ----- K - Kera‘s line segment[区间转二维平面+树状数组维护前缀最小最大值]

    题目链接 题目大意: 就是一个一维的数轴上面有一堆线段用一个三元组(l,r,val)(l,r,val)(l,r,val)表示. 现在我们有两个操作: 就是往数轴上面添加线段 询问[L,R][L,R][ ...

  5. Java中二维数组的用法(不定长二维数组)

    Java中二维数组的用法(不定长二维数组),即每个第二维的数组长度不一样. 1>代码如下: package com.demo.test;public class Test {public Tes ...

  6. php二维数组取交集,PHP中二维数组怎么取交集

    PHP中二维数组取交集的方法:首先循环其中一个数组:然后使用in_array()函数判断被循环数组的每个元素是否在另外一个数组中:最后输出$out_arr即可. PHP二维数组怎么取交集? 思路,循环 ...

  7. C#中二维数组的二维长度

    C#中二维数组的二维长度 二维数组的长度 int row = Arr.GetLength(0); //第一维的长度(即行数)int col = Arr.GetLength(1); //第二维的长度(即 ...

  8. python二维码识别读取_python+opencv检测图片中二维码

    缘起 需要检测发票中二维码的位置,以确定图像该怎么旋转,同时也可以为提取二维码信息创造先觉条件!(万恶的需求!) 失败的尝试--opencv训练大法 不感兴趣的可跳过不看! 解释:原文作者是训练检测舌 ...

  9. 本题要求编写程序,计算两个二维平面向量的和向量。

    本题要求编写程序,计算两个二维平面向量的和向量. 输入格式: 输入在一行中按照"x1​ y1​ x2​ y2​"的格式给出两个二维平面向量v1​=(x1​,y1​)和v2​=(x2 ...

  10. c语言中定义字母二维数组,C语言中二维字符数组

    C语言中二维字符数组的定义和初始化 一般来说,我们可能会希望定义一个二维字符数组并且在定义的时候就用一些字符串来初始化它.比如说: Code: 1.char testcase[30][MAX_LENG ...

最新文章

  1. oracle9i安装不上,终于成功安装oracle9i了(Cent OS 4.0+oracle9204)
  2. MongoDB之副本集
  3. MongoDB 和 NoSQL简介
  4. 再论c++模板之类型识别之如何得到类型信息
  5. 【EXLIBRIS】二十唯识白话译本【ZZ】
  6. 固体加热_干货分享| |固体氧化物燃料电池
  7. thrift java长连接_利用thrift在c++、java和python之间相互调用
  8. Linux内核调试方法总结【转】
  9. 软件测试工程师—从零到月入过万你只需要看这篇就够了(基础篇)
  10. ComponentPattern (组合模式)
  11. 【Java爬虫】爬取淘宝买家秀
  12. smart原则_人生工具:SWOT、PDCA、6W2H、SMART、WBS、时间管理、二八原则
  13. html怎么让音乐隐藏在网页中循环播放,怎么在网页中循环播放声音
  14. php以大写字母分割,js按大写字母拆分字符串
  15. 新网站做SEO最适合做哪些外链
  16. STL全特化 偏特化 成员特化
  17. 树莓派的浏览器无法上网
  18. 15.学习Camera之——camera理论基础和工作原理
  19. ubuntu + eigen3 安装(解决 fatal error: Eigen/Core: No such file or directory)
  20. 用python爬小说_使用python+Scrapy爬小说

热门文章

  1. gflags 调试内存_windows下堆异常调试神器--gflags
  2. 随机森林回归预测r语言_R包randomForest的随机森林回归模型以及对重要变量的选择...
  3. 向量与直线,梯度与法向量,切向量
  4. 德鲁克对管理学的贡献
  5. 图片文字识别python
  6. videojs-dynamic-watermark: video.js 视频添加文字水印
  7. 电路中的电阻_电感_电容的特性
  8. 教你用 Python 爬取 Baidu 文库全格式文档!
  9. 贱人工具箱使用技巧2——多重复制命令
  10. Comsol 2020全套教学视频 教程入门讲解新手的福音