import{_ as n,c as i,j as s,a as t,a4 as e,o as a}from"./chunks/framework.DpC1ZpOZ.js";const rs=JSON.parse('{"title":"mbcp.mp_math.line","description":"","frontmatter":{"title":"mbcp.mp_math.line","lastUpdated":false},"headers":[],"relativePath":"zht/api/mp_math/line.md","filePath":"zht/api/mp_math/line.md"}'),l={name:"zht/api/mp_math/line.md"},h=e('

模組 mbcp.mp_math.line

本模块定义了三维空间中的直线类

class Line3


method __init__(self, point: Point3, direction: Vector3)

説明: 三维空间中的直线。由一个点和一个方向向量确定。

變數説明:

源碼於GitHub上查看
python
def __init__(self, point: 'Point3', direction: 'Vector3'):\n    self.point = point\n    self.direction = direction

method approx(self, other: Line3, epsilon: float = APPROX) -> bool

説明: 判断两条直线是否近似相等。

變數説明:

返回: bool: 是否近似相等

源碼於GitHub上查看
python
def approx(self, other: 'Line3', epsilon: float=APPROX) -> bool:\n    return self.is_approx_parallel(other, epsilon) and (self.point - other.point).is_approx_parallel(self.direction, epsilon)

method cal_angle(self, other: Line3) -> AnyAngle

説明: 计算直线和直线之间的夹角。

變數説明:

返回: AnyAngle: 夹角

源碼於GitHub上查看
python
def cal_angle(self, other: 'Line3') -> 'AnyAngle':\n    return self.direction.cal_angle(other.direction)

method cal_distance(self, other: Line3 | Point3) -> float

説明: 计算直线和直线或点之间的距离。

',26),o={class:"tip custom-block"},p=s("p",{class:"custom-block-title"},"TIP",-1),r=s("p",null,"直线和直线之间的距离计算公式:",-1),k=s("li",null,"平行/重合 = 0",-1),d={class:"MathJax",jax:"SVG",style:{direction:"ltr",position:"relative"}},g={style:{overflow:"visible","min-height":"1px","min-width":"1px","vertical-align":"-1.391ex"},xmlns:"http://www.w3.org/2000/svg",width:"7.356ex",height:"4.296ex",role:"img",focusable:"false",viewBox:"0 -1284.3 3251.5 1899","aria-hidden":"true"},c=e('',1),m=[c],y=s("mjx-assistive-mml",{unselectable:"on",display:"inline",style:{top:"0px",left:"0px",clip:"rect(1px, 1px, 1px, 1px)","-webkit-touch-callout":"none","-webkit-user-select":"none","-khtml-user-select":"none","-moz-user-select":"none","-ms-user-select":"none","user-select":"none",position:"absolute",padding:"1px 0px 0px 0px",border:"0px",display:"block",width:"auto",overflow:"hidden"}},[s("math",{xmlns:"http://www.w3.org/1998/Math/MathML"},[s("mfrac",null,[s("mrow",null,[s("mo",{"data-mjx-texclass":"ORD",stretchy:"false"},"|"),s("mrow",{"data-mjx-texclass":"ORD"},[s("mover",null,[s("mrow",null,[s("msub",null,[s("mi",null,"P"),s("mn",null,"1")]),s("msub",null,[s("mi",null,"P"),s("mn",null,"2")])]),s("mo",{stretchy:"false"},"→")])]),s("mo",null,"×"),s("mrow",{"data-mjx-texclass":"ORD"},[s("mover",null,[s("mi",null,"v"),s("mo",{stretchy:"false"},"→")])]),s("mo",{"data-mjx-texclass":"ORD",stretchy:"false"},"|")]),s("mrow",null,[s("mo",{"data-mjx-texclass":"ORD",stretchy:"false"},"|"),s("mrow",{"data-mjx-texclass":"ORD"},[s("mover",null,[s("mi",null,"v"),s("mo",{stretchy:"false"},"→")])]),s("mo",{"data-mjx-texclass":"ORD",stretchy:"false"},"|")])])])],-1),E={class:"MathJax",jax:"SVG",style:{direction:"ltr",position:"relative"}},Q={style:{overflow:"visible","min-height":"1px","min-width":"1px","vertical-align":"-0.339ex"},xmlns:"http://www.w3.org/2000/svg",width:"2.44ex",height:"1.885ex",role:"img",focusable:"false",viewBox:"0 -683 1078.6 833","aria-hidden":"true"},u=e('',1),T=[u],b=s("mjx-assistive-mml",{unselectable:"on",display:"inline",style:{top:"0px",left:"0px",clip:"rect(1px, 1px, 1px, 1px)","-webkit-touch-callout":"none","-webkit-user-select":"none","-khtml-user-select":"none","-moz-user-select":"none","-ms-user-select":"none","user-select":"none",position:"absolute",padding:"1px 0px 0px 0px",border:"0px",display:"block",width:"auto",overflow:"hidden"}},[s("math",{xmlns:"http://www.w3.org/1998/Math/MathML"},[s("msub",null,[s("mi",null,"P"),s("mn",null,"1")])])],-1),f={class:"MathJax",jax:"SVG",style:{direction:"ltr",position:"relative"}},F={style:{overflow:"visible","min-height":"1px","min-width":"1px","vertical-align":"-0.339ex"},xmlns:"http://www.w3.org/2000/svg",width:"2.44ex",height:"1.885ex",role:"img",focusable:"false",viewBox:"0 -683 1078.6 833","aria-hidden":"true"},_=e('',1),C=[_],x=s("mjx-assistive-mml",{unselectable:"on",display:"inline",style:{top:"0px",left:"0px",clip:"rect(1px, 1px, 1px, 1px)","-webkit-touch-callout":"none","-webkit-user-select":"none","-khtml-user-select":"none","-moz-user-select":"none","-ms-user-select":"none","user-select":"none",position:"absolute",padding:"1px 0px 0px 0px",border:"0px",display:"block",width:"auto",overflow:"hidden"}},[s("math",{xmlns:"http://www.w3.org/1998/Math/MathML"},[s("msub",null,[s("mi",null,"P"),s("mn",null,"2")])])],-1),w={class:"MathJax",jax:"SVG",style:{direction:"ltr",position:"relative"}},v={style:{overflow:"visible","min-height":"1px","min-width":"1px","vertical-align":"-0.025ex"},xmlns:"http://www.w3.org/2000/svg",width:"1.097ex",height:"1.939ex",role:"img",focusable:"false",viewBox:"0 -846 485 857","aria-hidden":"true"},D=e('',1),A=[D],B=s("mjx-assistive-mml",{unselectable:"on",display:"inline",style:{top:"0px",left:"0px",clip:"rect(1px, 1px, 1px, 1px)","-webkit-touch-callout":"none","-webkit-user-select":"none","-khtml-user-select":"none","-moz-user-select":"none","-ms-user-select":"none","user-select":"none",position:"absolute",padding:"1px 0px 0px 0px",border:"0px",display:"block",width:"auto",overflow:"hidden"}},[s("math",{xmlns:"http://www.w3.org/1998/Math/MathML"},[s("mrow",{"data-mjx-texclass":"ORD"},[s("mover",null,[s("mi",null,"v"),s("mo",{stretchy:"false"},"→")])])])],-1),L={class:"tip custom-block"},H=s("p",{class:"custom-block-title"},"TIP",-1),V=s("p",null,"直线和点之间的距离计算公式:",-1),P={tabindex:"0",class:"MathJax",jax:"SVG",display:"true",style:{direction:"ltr",display:"block","text-align":"center",margin:"1em 0",position:"relative"}},q={style:{overflow:"visible","min-height":"1px","min-width":"1px","vertical-align":"-2.388ex"},xmlns:"http://www.w3.org/2000/svg",width:"10.256ex",height:"6.45ex",role:"img",focusable:"false",viewBox:"0 -1795.5 4533 2851","aria-hidden":"true"},M=e('',1),j=[M],S=s("mjx-assistive-mml",{unselectable:"on",display:"block",style:{top:"0px",left:"0px",clip:"rect(1px, 1px, 1px, 1px)","-webkit-touch-callout":"none","-webkit-user-select":"none","-khtml-user-select":"none","-moz-user-select":"none","-ms-user-select":"none","user-select":"none",position:"absolute",padding:"1px 0px 0px 0px",border:"0px",display:"block",overflow:"hidden",width:"100%"}},[s("math",{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block"},[s("mfrac",null,[s("mrow",null,[s("mo",{"data-mjx-texclass":"ORD",stretchy:"false"},"|"),s("mrow",{"data-mjx-texclass":"ORD"},[s("mover",null,[s("mrow",null,[s("msub",null,[s("mi",null,"P"),s("mn",null,"1")]),s("mi",null,"P")]),s("mo",{stretchy:"false"},"→")])]),s("mo",null,"×"),s("mrow",{"data-mjx-texclass":"ORD"},[s("mover",null,[s("mi",null,"v"),s("mo",{stretchy:"false"},"→")])]),s("mo",{"data-mjx-texclass":"ORD",stretchy:"false"},"|")]),s("mrow",null,[s("mo",{"data-mjx-texclass":"ORD",stretchy:"false"},"|"),s("mrow",{"data-mjx-texclass":"ORD"},[s("mover",null,[s("mi",null,"v"),s("mo",{stretchy:"false"},"→")])]),s("mo",{"data-mjx-texclass":"ORD",stretchy:"false"},"|")])])])],-1),Z={class:"MathJax",jax:"SVG",style:{direction:"ltr",position:"relative"}},O={style:{overflow:"visible","min-height":"1px","min-width":"1px","vertical-align":"-0.339ex"},xmlns:"http://www.w3.org/2000/svg",width:"2.44ex",height:"1.885ex",role:"img",focusable:"false",viewBox:"0 -683 1078.6 833","aria-hidden":"true"},R=e('',1),G=[R],N=s("mjx-assistive-mml",{unselectable:"on",display:"inline",style:{top:"0px",left:"0px",clip:"rect(1px, 1px, 1px, 1px)","-webkit-touch-callout":"none","-webkit-user-select":"none","-khtml-user-select":"none","-moz-user-select":"none","-ms-user-select":"none","user-select":"none",position:"absolute",padding:"1px 0px 0px 0px",border:"0px",display:"block",width:"auto",overflow:"hidden"}},[s("math",{xmlns:"http://www.w3.org/1998/Math/MathML"},[s("msub",null,[s("mi",null,"P"),s("mn",null,"1")])])],-1),I={class:"MathJax",jax:"SVG",style:{direction:"ltr",position:"relative"}},z={style:{overflow:"visible","min-height":"1px","min-width":"1px","vertical-align":"0"},xmlns:"http://www.w3.org/2000/svg",width:"1.699ex",height:"1.545ex",role:"img",focusable:"false",viewBox:"0 -683 751 683","aria-hidden":"true"},X=s("g",{stroke:"currentColor",fill:"currentColor","stroke-width":"0",transform:"scale(1,-1)"},[s("g",{"data-mml-node":"math"},[s("g",{"data-mml-node":"mi"},[s("path",{"data-c":"1D443",d:"M287 628Q287 635 230 637Q206 637 199 638T192 648Q192 649 194 659Q200 679 203 681T397 683Q587 682 600 680Q664 669 707 631T751 530Q751 453 685 389Q616 321 507 303Q500 302 402 301H307L277 182Q247 66 247 59Q247 55 248 54T255 50T272 48T305 46H336Q342 37 342 35Q342 19 335 5Q330 0 319 0Q316 0 282 1T182 2Q120 2 87 2T51 1Q33 1 33 11Q33 13 36 25Q40 41 44 43T67 46Q94 46 127 49Q141 52 146 61Q149 65 218 339T287 628ZM645 554Q645 567 643 575T634 597T609 619T560 635Q553 636 480 637Q463 637 445 637T416 636T404 636Q391 635 386 627Q384 621 367 550T332 412T314 344Q314 342 395 342H407H430Q542 342 590 392Q617 419 631 471T645 554Z",style:{"stroke-width":"3"}})])])],-1),J=[X],$=s("mjx-assistive-mml",{unselectable:"on",display:"inline",style:{top:"0px",left:"0px",clip:"rect(1px, 1px, 1px, 1px)","-webkit-touch-callout":"none","-webkit-user-select":"none","-khtml-user-select":"none","-moz-user-select":"none","-ms-user-select":"none","user-select":"none",position:"absolute",padding:"1px 0px 0px 0px",border:"0px",display:"block",width:"auto",overflow:"hidden"}},[s("math",{xmlns:"http://www.w3.org/1998/Math/MathML"},[s("mi",null,"P")])],-1),U={class:"MathJax",jax:"SVG",style:{direction:"ltr",position:"relative"}},K={style:{overflow:"visible","min-height":"1px","min-width":"1px","vertical-align":"-0.025ex"},xmlns:"http://www.w3.org/2000/svg",width:"1.097ex",height:"1.939ex",role:"img",focusable:"false",viewBox:"0 -846 485 857","aria-hidden":"true"},W=e('',1),Y=[W],ss=s("mjx-assistive-mml",{unselectable:"on",display:"inline",style:{top:"0px",left:"0px",clip:"rect(1px, 1px, 1px, 1px)","-webkit-touch-callout":"none","-webkit-user-select":"none","-khtml-user-select":"none","-moz-user-select":"none","-ms-user-select":"none","user-select":"none",position:"absolute",padding:"1px 0px 0px 0px",border:"0px",display:"block",width:"auto",overflow:"hidden"}},[s("math",{xmlns:"http://www.w3.org/1998/Math/MathML"},[s("mrow",{"data-mjx-texclass":"ORD"},[s("mover",null,[s("mi",null,"v"),s("mo",{stretchy:"false"},"→")])])])],-1),is=e(`

變數説明:

返回: float: 距离

抛出:

源碼於GitHub上查看
python
def cal_distance(self, other: 'Line3 | Point3') -> float:
    if isinstance(other, Line3):
        if self == other:
            return 0
        elif self.is_parallel(other):
            return (other.point - self.point).cross(self.direction).length / self.direction.length
        elif not self.is_coplanar(other):
            return abs(self.direction.cross(other.direction) @ (self.point - other.point) / self.direction.cross(other.direction).length)
        else:
            return 0
    elif isinstance(other, Point3):
        return (other - self.point).cross(self.direction).length / self.direction.length
    else:
        raise TypeError('Unsupported type.')

method cal_intersection(self, other: Line3) -> Point3

説明: 计算两条直线的交点。

變數説明:

返回: Point3: 交点

抛出:

源碼於GitHub上查看
python
def cal_intersection(self, other: 'Line3') -> 'Point3':
    if self.is_parallel(other):
        raise ValueError('Lines are parallel and do not intersect.')
    if not self.is_coplanar(other):
        raise ValueError('Lines are not coplanar and do not intersect.')
    return self.point + self.direction.cross(other.direction) @ other.direction.cross(self.point - other.point) / self.direction.cross(other.direction).length ** 2 * self.direction

method cal_perpendicular(self, point: Point3) -> Line3

説明: 计算直线经过指定点p的垂线。

變數説明:

返回: Line3: 垂线

源碼於GitHub上查看
python
def cal_perpendicular(self, point: 'Point3') -> 'Line3':
    return Line3(point, self.direction.cross(point - self.point))

method get_point(self, t: RealNumber) -> Point3

説明: 获取直线上的点。同一条直线,但起始点和方向向量不同,则同一个t对应的点不同。

變數説明:

返回: Point3: 点

源碼於GitHub上查看
python
def get_point(self, t: RealNumber) -> 'Point3':
    return self.point + t * self.direction

method get_parametric_equations(self) -> tuple[OneSingleVarFunc, OneSingleVarFunc, OneSingleVarFunc]

説明: 获取直线的参数方程。

返回: tuple[OneSingleVarFunc, OneSingleVarFunc, OneSingleVarFunc]: 参数方程

源碼於GitHub上查看
python
def get_parametric_equations(self) -> tuple[OneSingleVarFunc, OneSingleVarFunc, OneSingleVarFunc]:
    return (lambda t: self.point.x + self.direction.x * t, lambda t: self.point.y + self.direction.y * t, lambda t: self.point.z + self.direction.z * t)

method is_approx_parallel(self, other: Line3, epsilon: float = 1e-06) -> bool

説明: 判断两条直线是否近似平行。

變數説明:

返回: bool: 是否近似平行

源碼於GitHub上查看
python
def is_approx_parallel(self, other: 'Line3', epsilon: float=1e-06) -> bool:
    return self.direction.is_approx_parallel(other.direction, epsilon)

method is_parallel(self, other: Line3) -> bool

説明: 判断两条直线是否平行。

變數説明:

返回: bool: 是否平行

源碼於GitHub上查看
python
def is_parallel(self, other: 'Line3') -> bool:
    return self.direction.is_parallel(other.direction)

method is_collinear(self, other: Line3) -> bool

説明: 判断两条直线是否共线。

變數説明:

返回: bool: 是否共线

源碼於GitHub上查看
python
def is_collinear(self, other: 'Line3') -> bool:
    return self.is_parallel(other) and (self.point - other.point).is_parallel(self.direction)

method is_point_on(self, point: Point3) -> bool

説明: 判断点是否在直线上。

變數説明:

返回: bool: 是否在直线上

源碼於GitHub上查看
python
def is_point_on(self, point: 'Point3') -> bool:
    return (point - self.point).is_parallel(self.direction)

method is_coplanar(self, other: Line3) -> bool

説明: 判断两条直线是否共面。 充要条件:两直线方向向量的叉乘与两直线上任意一点的向量的点积为0。

變數説明:

返回: bool: 是否共面

源碼於GitHub上查看
python
def is_coplanar(self, other: 'Line3') -> bool:
    return self.direction.cross(other.direction) @ (self.point - other.point) == 0

method simplify(self)

説明: 简化直线方程,等价相等。 自体简化,不返回值。

按照可行性一次对x y z 化 0 处理,并对向量单位化

源碼於GitHub上查看
python
def simplify(self):
    self.direction.normalize()
    if self.direction.x == 0:
        self.point.x = 0
    if self.direction.y == 0:
        self.point.y = 0
    if self.direction.z == 0:
        self.point.z = 0

@classmethod

method from_two_points(cls, p1: Point3, p2: Point3) -> Line3

説明: 工厂函数 由两点构造直线。

變數説明:

返回: Line3: 直线

源碼於GitHub上查看
python
@classmethod
def from_two_points(cls, p1: 'Point3', p2: 'Point3') -> 'Line3':
    direction = p2 - p1
    return cls(p1, direction)

method self & other: Line3 => Line3 | Point3 | None

説明: 计算两条直线点集合的交集。重合线返回自身,平行线返回None,交线返回交点。

變數説明:

返回: Line3 | Point3 | None: 交集

源碼於GitHub上查看
python
def __and__(self, other: 'Line3') -> 'Line3 | Point3 | None':
    if self.is_collinear(other):
        return self
    elif self.is_parallel(other) or not self.is_coplanar(other):
        return None
    else:
        return self.cal_intersection(other)

method self == other => bool

説明: 判断两条直线是否等价。

v1 // v2 ∧ (p1 - p2) // v1

變數説明:

返回: bool: 是否等价

源碼於GitHub上查看
python
def __eq__(self, other) -> bool:
    return self.direction.is_parallel(other.direction) and (self.point - other.point).is_parallel(self.direction)
`,97);function ts(as,es,ns,ls,hs,os){return a(),i("div",null,[h,s("div",o,[p,r,s("ul",null,[k,s("li",null,[t("平行/异面 = "),s("mjx-container",d,[(a(),i("svg",g,m)),y])]),s("li",null,[t("相交 = 0 其中,"),s("mjx-container",E,[(a(),i("svg",Q,T)),b]),t("和"),s("mjx-container",f,[(a(),i("svg",F,C)),x]),t("分别为两条直线上的点,"),s("mjx-container",w,[(a(),i("svg",v,A)),B]),t("为直线的方向向量。")])])]),s("div",L,[H,V,s("mjx-container",P,[(a(),i("svg",q,j)),S]),s("p",null,[t("其中,"),s("mjx-container",Z,[(a(),i("svg",O,G)),N]),t("为直线上的点,"),s("mjx-container",I,[(a(),i("svg",z,J)),$]),t("为点,"),s("mjx-container",U,[(a(),i("svg",K,Y)),ss]),t("为直线的方向向量。")])]),is])}const ks=n(l,[["render",ts]]);export{rs as __pageData,ks as default};