主頁 > 企業開發 > 如何獲得垂直于彈跳角的角度或向量3點?

如何獲得垂直于彈跳角的角度或向量3點?

2021-10-15 19:09:52 企業開發

我試圖找到向量或角度,以計算兩條“粗”線相交的點。最終目標是為粗線渲染器繪制簡單的平面。

盡管我正在使用 Unity 并且正在使用 Vector3,但出于我的目的,假設 Z 值始終為 0。這是一個二維問題。不是Unity 特定的問題,我不確定為什么我很難找到我能理解的解決方案。獲得繪制“粗”線的分數肯定不是什么新鮮事。但是對于我的生活,我找不到解決方案。

我最接近的是找出垂直于我想要的線的點。我知道這是“反彈”線。換句話說,假設中間點是臺球桌側面的撞擊點,我可以通過 3 個點獲得表示臺球桌側面的線的向量。我想要的是垂直于那條邊的向量。我根據這里的帖子計算出下面的代碼:如何獲得垂直于彈跳角的角度或向量 3 點? 如何獲得垂直于彈跳角的角度或向量 3 點?

uj5u.com熱心網友回復:

不是 100% 確定這里的預期邏輯,但在你的代碼中對我來說似乎很棘手的部分是這樣的:

Vector3 n1 = (p2 - p1).normalized;
Vector3 n2 = (p3 - p2).normalized;

在這里,您將獲得一條線的法線和另一條線的反轉法線,然后將它們相加。這會導致您描述的“彈跳墻”線,因為您在交叉點上鏡像了一個法線。你不是說:

Vector3 n1 = (p3 - p2).normalized;
Vector3 n2 = (p1 - p2).normalized;

當您通過解決該問題使標志相同時,兩條法線都位于交點的一側。將它們加在一起會導致 y 分量在某種程度上相互抵消,并且 x 分量位于交點的正確一側。繪制的藍線然后采用您想要的角度(紅色固定法線):

如何獲得垂直于彈跳角的角度或向量 3 點?

我用來做這個的代碼的完整修改版本:

using UnityEngine;

public class ThickLineRenderer : MonoBehaviour {
    public Vector3 line1Start = new Vector3(-1, -1);
    public Vector3 intersect = new Vector3(0, 0);
    public Vector3 line2Start = new Vector3(-1, 1);

    private void OnDrawGizmos() {
        Vector3[] points = new Vector3[] { line1Start, intersect, line2Start };

        Vector3 p1 = points[0];
        Vector3 p2 = points[1];
        Vector3 p3 = points[2];

        Gizmos.color = Color.white;
        Gizmos.DrawLine(p1, p2);
        Gizmos.DrawLine(p2, p3);

        Vector3 n1 = (p3 - p2).normalized;
        Vector3 n2 = (p1 - p2).normalized;
        Gizmos.color = Color.red;
        Gizmos.DrawLine(p2, n1);
        Gizmos.DrawLine(p2, n2);

        Vector3 n = (n1   n2).normalized;

        Vector3 d = p2   n;
        Vector3 d2 = p2 - n;

        Gizmos.color = Color.blue;
        Gizmos.DrawLine(p2, d);
        Gizmos.DrawLine(p2, d2);
    }
}

(對不起,我沒有完全正確的詞匯來描述這個問題,距三角學已經很長時間了。希望這是有道理的。)

uj5u.com熱心網友回復:

您好,我不確定我是否真的理解您要完成的任務,但對我而言,您的問題看起來像這樣,您得到了三個點 P1、P2、P3,并且您希望準確找到“法線角度”,即 P12 之間的黃色角度和 P23 線。

一種方法是計算絕對角度,這意味著 x 軸和每個線段之間形成的角度。在下圖中,它們是橙色和紫色的角度。然后減法會告訴你 P12 和 P23 之間形成的角度,這是綠色角度。最后,為了獲得我認為的所謂的“法線角”,它恰好位于綠色角的中間,在這種情況下,您只需要從較大的角減去綠色角的一半,即紫色角。

如何獲得垂直于彈跳角的角度或向量 3 點?

我做了一個簡單的控制臺程式來進行計算here'sthe code

using System;

namespace ConsoleApp1
{
    class Program
    {
        public static double GetAbsAngle(double x, double y)
        {
            double radsAbsAngle;
            //Get the absolute angle from respect to the x axis given a podouble x,y
            if (y > 0)
            {
                radsAbsAngle = Math.Atan2(y, x);
                return radsAbsAngle;
            }
            //Here Math.Atan2(y, x) will always result negative
            radsAbsAngle = 2*Math.PI Math.Atan2(y, x);
            return radsAbsAngle;
        }
        public static double AngleBetweenPoints(double x1, double y1, double x2, double y2)
        {
            double absAngleP1 = Program.GetAbsAngle(x1, y1);
            Console.WriteLine("Abs angle P1 in degrees: {0}", Program.RadiansToDegrees(absAngleP1));
            double absAngleP2 = Program.GetAbsAngle(x2, y2);
            Console.WriteLine("Abs angle P2 in degrees: {0}", Program.RadiansToDegrees(absAngleP2));
            double angleBetween;
            angleBetween = (x1 > x2) ? absAngleP1 - absAngleP2 : absAngleP2 - absAngleP1;
            return angleBetween;
        }
        public static double RadiansToDegrees(double radians)
        {
            double degrees = (180 / Math.PI) * radians;
            return (degrees);
        }
        static void Main(string[] args)
        {
            //P1 with 
            double x1 = -4;
            double y1 = 4;
            //Assuming that P2 is always at 0,0
            //P3 with
            double x3 = -4;
            double y3 = -4;

            double angleBetween = Program.AngleBetweenPoints(x1, y1, x3, y3);
            Console.WriteLine("Angle between P1 and P3 in degrees: {0}",Program.RadiansToDegrees(angleBetween));
            double p1Angle = Program.GetAbsAngle(x1, y1);
            double p3Angle = Program.GetAbsAngle(x3, y3);
            double absNormalAngle = (p1Angle > p3Angle) ? p1Angle - (angleBetween/ 2) : p3Angle - (angleBetween / 2);
            Console.WriteLine("The normal abs angle between P1 and P3 in degrees: {0}", Program.RadiansToDegrees(absNormalAngle));
        }
        
    }
}

結果如下

Abs angle P1 in degrees: 135
Abs angle P2 in degrees: 225
Angle between P1 and P3 in degrees: 90
The normal abs angle between P1 and P3 in degrees: 180

uj5u.com熱心網友回復:

我為 nonce 提出了一個解決方案,該解決方案依賴于使用平行線和線交點來找到繪制“粗”線所需的角點。

我并不完全相信這是正確的方法,并且愿意接受更好的答案(或編輯這個答案)。然而,我希望一個有效的答案將有助于產生更好的答案。

下圖顯示了我的最終結果。是的,如果 p1 == p3 有明顯的問題。銳角同樣會引起問題。但是,目前這適用于我的用例。

using System;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(MeshRenderer))]
[RequireComponent(typeof(MeshFilter))]
public class OutlineRenderer : MonoBehaviour {
  //Add 5 GameObjects as children to this one at:
  //0, 0, 0
  //12, 4.5, 0
  //10, -0.5, 0
  //15, -6, 0
  //2, -6, 0
  public GameObject[] points;

  private void OnDrawGizmos() {
    //Hold a list of corner vertices alternating by left-right as the line progresses.
    List<Vector2> corners = new List<Vector2>();

    //For now, thickness is an inverse-multiplier.
    //With a little extra math, it can be converted to a scalar unit.
    float thickness = 1.5f;

    //This logic is going to connect the line into a loop (which is my end use-case).
    //For a straight line, modify the logic for the starting and ending vertices.
    for (int i = 0; i < points.Length; i  ) {
      //The prev point. If p2 is index 0, then p1 is the last point in the list.
      Vector3 p1 = i > 0 ? points[i - 1].transform.position : points[points.Length - 1].transform.position; 
      //The current point.
      Vector3 p2 = points[i].transform.position;
  
      float dist = Vector2.Distance(p1, p2);
  
      float dx = p2.x - p1.x;
      float dy = p2.y - p1.y;
  
      dx /= dist * thickness;
      dy /= dist * thickness;

      Vector3 a = new Vector3(-dy   p1.x, dx   p1.y);
      Vector3 b = new Vector3(dy   p1.x, -dx   p1.y);
      Vector3 a2 = a   new Vector3(dx, dy);
      Vector3 b2 = b   new Vector3(dx, dy);

      //----------------------------------------
      //The next point. If p2 is the last index, then p3 is the first point in the list.
      Vector3 p3 = i < points.Length - 1 ? points[i   1].transform.position : points[0].transform.position;

      dist = Vector2.Distance(p3, p2);

      dx = p2.x - p3.x;
      dy = p2.y - p3.y;

      dx /= dist * thickness;
      dy /= dist * thickness;

      Vector3 c = new Vector3(dy   p3.x, -dx   p3.y);
      Vector3 d = new Vector3(-dy   p3.x, dx   p3.y);
      Vector3 c2 = c   new Vector3(dx, dy);
      Vector3 d2 = d   new Vector3(dx, dy);
  
      Vector2 i1 = findSegmentIntersection(a, a2, c, c2);
      Vector2 i2 = findSegmentIntersection(b, b2, d, d2);

      corners.Add(i1);
      corners.Add(i2);
    }

    //Corners are the actual vertices I'm going to need.
    //Draw logic (for Gizmos only).
    //Mesh rendering is completely separate.
    int n = corners.Count;
    for (int i = 0; i < n - 2; i  = 2) {
      Vector3 p = points[i / 2].transform.position;
      Gizmos.color = Color.blue;
      Gizmos.DrawLine(p, corners[i]);
      Gizmos.DrawLine(p, corners[i   1]);
      Gizmos.color = Color.red;
      Gizmos.DrawLine(corners[i], corners[i   2]);
      Gizmos.DrawLine(corners[i   1], corners[i   3]);
    }
    Gizmos.color = Color.blue;
    Gizmos.DrawLine(points[points.Length - 1].transform.position, corners[n - 2]);
    Gizmos.DrawLine(points[points.Length - 1].transform.position, corners[n - 1]);
    Gizmos.color = Color.red;
    Gizmos.DrawLine(corners[n - 2], corners[0]);
    Gizmos.DrawLine(corners[n - 1], corners[1]);
  }

  //A utility method I converted from ActionScript.
  //There's probably something in the Unity library that can also do it.
  public Vector2 findSegmentIntersection(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4) {
    var x1 = p1.x;
    var x2 = p2.x;
    var x3 = p3.x;
    var x4 = p4.x;
    var y1 = p1.y;
    var y2 = p2.y;
    var y3 = p3.y;
    var y4 = p4.y;
    var z1 = x1 - x2;
    var z2 = x3 - x4;
    var z3 = y1 - y2;
    var z4 = y3 - y4;
    var d = z1 * z4 - z3 * z2;

    //If d is zero, there is no intersection.
    if (d == 0) {
      throw new Exception("Lines do not intersect!");
    }

    //Get the x and y.
    var pre = x1 * y2 - y1 * x2;
    var post = x3 * y4 - y3 * x4;
    var x = (pre * z2 - z1 * post) / d;
    var y = (pre * z4 - z3 * post) / d;

    //Return the point of intersection.
    return new Vector2(x, y);
  }
}

如何獲得垂直于彈跳角的角度或向量 3 點?

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/316210.html

標籤:C# 统一3d 向量 线 线交点

上一篇:Unity2D-如何檢查我的游戲物件/精靈是否低于ceratinYlvl?

下一篇:Unity碰撞時受到傷害

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • IEEE1588PTP在數字化變電站時鐘同步方面的應用

    IEEE1588ptp在數字化變電站時鐘同步方面的應用 京準電子科技官微——ahjzsz 一、電力系統時間同步基本概況 隨著對IEC 61850標準研究的不斷深入,國內外學者提出基于IEC61850通信標準體系建設數字化變電站的發展思路。數字化變電站與常規變電站的顯著區別在于程序層傳統的電流/電壓互 ......

    uj5u.com 2020-09-10 03:51:52 more
  • HTTP request smuggling CL.TE

    CL.TE 簡介 前端通過Content-Length處理請求,通過反向代理或者負載均衡將請求轉發到后端,后端Transfer-Encoding優先級較高,以TE處理請求造成安全問題。 檢測 發送如下資料包 POST / HTTP/1.1 Host: ac391f7e1e9af821806e890 ......

    uj5u.com 2020-09-10 03:52:11 more
  • 網路滲透資料大全單——漏洞庫篇

    網路滲透資料大全單——漏洞庫篇漏洞庫 NVD ——美國國家漏洞庫 →http://nvd.nist.gov/。 CERT ——美國國家應急回應中心 →https://www.us-cert.gov/ OSVDB ——開源漏洞庫 →http://osvdb.org Bugtraq ——賽門鐵克 →ht ......

    uj5u.com 2020-09-10 03:52:15 more
  • 京準講述NTP時鐘服務器應用及原理

    京準講述NTP時鐘服務器應用及原理京準講述NTP時鐘服務器應用及原理 安徽京準電子科技官微——ahjzsz 北斗授時原理 授時是指接識訓通過某種方式獲得本地時間與北斗標準時間的鐘差,然后調整本地時鐘使時差控制在一定的精度范圍內。 衛星導航系統通常由三部分組成:導航授時衛星、地面檢測校正維護系統和用戶 ......

    uj5u.com 2020-09-10 03:52:25 more
  • 利用北斗衛星系統設計NTP網路時間服務器

    利用北斗衛星系統設計NTP網路時間服務器 利用北斗衛星系統設計NTP網路時間服務器 安徽京準電子科技官微——ahjzsz 概述 NTP網路時間服務器是一款支持NTP和SNTP網路時間同步協議,高精度、大容量、高品質的高科技時鐘產品。 NTP網路時間服務器設備采用冗余架構設計,高精度時鐘直接來源于北斗 ......

    uj5u.com 2020-09-10 03:52:35 more
  • 詳細解讀電力系統各種對時方式

    詳細解讀電力系統各種對時方式 詳細解讀電力系統各種對時方式 安徽京準電子科技官微——ahjzsz,更多資料請添加VX 衛星同步時鐘是我京準公司開發研制的應用衛星授時時技術的標準時間顯示和發送的裝置,該裝置以M國全球定位系統(GLOBAL POSITIONING SYSTEM,縮寫為GPS)或者我國北 ......

    uj5u.com 2020-09-10 03:52:45 more
  • 如何保證外包團隊接入企業內網安全

    不管企業規模的大小,只要企業想省錢,那么企業的某些服務就一定會采用外包的形式,然而看似美好又經濟的策略,其實也有不好的一面。下面我通過安全的角度來聊聊使用外包團的安全隱患問題。 先看看什么服務會使用外包的,最常見的就是話務/客服這種需要大量重復性、無技術性的服務,或者是一些銷售外包、特殊的職能外包等 ......

    uj5u.com 2020-09-10 03:52:57 more
  • PHP漏洞之【整型數字型SQL注入】

    0x01 什么是SQL注入 SQL是一種注入攻擊,通過前端帶入后端資料庫進行惡意的SQL陳述句查詢。 0x02 SQL整型注入原理 SQL注入一般發生在動態網站URL地址里,當然也會發生在其它地發,如登錄框等等也會存在注入,只要是和資料庫打交道的地方都有可能存在。 如這里http://192.168. ......

    uj5u.com 2020-09-10 03:55:40 more
  • [GXYCTF2019]禁止套娃

    git泄露獲取原始碼 使用GET傳參,引數為exp 經過三層過濾執行 第一層過濾偽協議,第二層過濾帶引數的函式,第三層過濾一些函式 preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'] (?R)參考當前正則運算式,相當于匹配函式里的引數 因此傳遞 ......

    uj5u.com 2020-09-10 03:56:07 more
  • 等保2.0實施流程

    流程 結論 ......

    uj5u.com 2020-09-10 03:56:16 more
最新发布
  • 使用Django Rest framework搭建Blog

    在前面的Blog例子中我們使用的是GraphQL, 雖然GraphQL的使用處于上升趨勢,但是Rest API還是使用的更廣泛一些. 所以還是決定回到傳統的rest api framework上來, Django rest framework的官網上給了一個很好用的QuickStart, 我參考Qu ......

    uj5u.com 2023-04-20 08:17:54 more
  • 記錄-new Date() 我忍你很久了!

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 大家平時在開發的時候有沒被new Date()折磨過?就是它的諸多怪異的設定讓你每每用的時候,都可能不小心踩坑。造成程式意外出錯,卻一下子找不到問題出處,那叫一個煩透了…… 下面,我就列舉它的“四宗罪”及應用思考 可惡的四宗罪 1. Sa ......

    uj5u.com 2023-04-20 08:17:47 more
  • 使用Vue.js實作文字跑馬燈效果

    實作文字跑馬燈效果,首先用到 substring()截取 和 setInterval計時器 clearInterval()清除計時器 效果如下: 實作代碼如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta ......

    uj5u.com 2023-04-20 08:12:31 more
  • JavaScript 運算子

    JavaScript 運算子/運算子 在 JavaScript 中,有一些運算子可以使代碼更簡潔、易讀和高效。以下是一些常見的運算子: 1、可選鏈運算子(optional chaining operator) ?.是可選鏈運算子(optional chaining operator)。?. 可選鏈操 ......

    uj5u.com 2023-04-20 08:02:25 more
  • CSS—相對單位rem

    一、概述 rem是一個相對長度單位,它的單位長度取決于根標簽html的字體尺寸。rem即root em的意思,中文翻譯為根em。瀏覽器的文本尺寸一般默認為16px,即默認情況下: 1rem = 16px rem布局原理:根據CSS媒體查詢功能,更改根標簽的字體尺寸,實作rem單位隨螢屏尺寸的變化,如 ......

    uj5u.com 2023-04-20 08:02:21 more
  • 我的第一個NPM包:panghu-planebattle-esm(胖虎飛機大戰)使用說明

    好家伙,我的包終于開發完啦 歡迎使用胖虎的飛機大戰包!! 為你的主頁添加色彩 這是一個有趣的網頁小游戲包,使用canvas和js開發 使用ES6模塊化開發 效果圖如下: (覺得圖片太sb的可以自己改) 代碼已開源!! Git: https://gitee.com/tang-and-han-dynas ......

    uj5u.com 2023-04-20 08:01:50 more
  • 如何在 vue3 中使用 jsx/tsx?

    我們都知道,通常情況下我們使用 vue 大多都是用的 SFC(Signle File Component)單檔案組件模式,即一個組件就是一個檔案,但其實 Vue 也是支持使用 JSX 來撰寫組件的。這里不討論 SFC 和 JSX 的好壞,這個仁者見仁智者見智。本篇文章旨在帶領大家快速了解和使用 Vu ......

    uj5u.com 2023-04-20 08:01:37 more
  • 【Vue2.x原始碼系列06】計算屬性computed原理

    本章目標:計算屬性是如何實作的?計算屬性快取原理以及洋蔥模型的應用?在初始化Vue實體時,我們會給每個計算屬性都創建一個對應watcher,我們稱之為計算屬性watcher ......

    uj5u.com 2023-04-20 08:01:31 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:01:10 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:00:32 more