manimgeo.components.line.adapter 源代码

from __future__ import annotations

from ...math import (
    close,
    is_point_on_line,
    vertical_point_to_line,
    vertical_line_unit_direction,
)
from pydantic import Field
from typing import cast
import numpy as np

from ..base import GeometryAdapter
from .args import *

[文档] class LineAdapter(GeometryAdapter[LineConstructArgs]): # 继承 GeometryAdapter 并指定参数模型类型 start: np.ndarray = Field(default=np.zeros(3), description="计算线首坐标", init=False) end: np.ndarray = Field(default=np.zeros(3), description="计算线尾坐标", init=False) length: Number = Field(default=0.0, description="计算线长度", init=False) unit_direction: np.ndarray = Field(default=np.zeros(3), description="计算线单位方向向量", init=False) def __call__(self): """根据 self.args 执行具体计算""" match self.construct_type: case "PP": args = cast(PPArgs, self.args) self.start = args.point1.coord self.end = args.point2.coord case "PV": args = cast(PVArgs, self.args) self.start = args.start.coord self.end = args.start.coord + args.vector.vec case "TranslationLV": args = cast(TranslationLVArgs, self.args) self.start = args.line.start + args.vector.vec self.end = args.line.end + args.vector.vec case "VerticalPL": args = cast(VerticalPLArgs, self.args) if not is_point_on_line(args.point.coord, args.line.start, args.line.end): self.start = vertical_point_to_line(args.point.coord, args.line.start, args.line.end) self.end = args.point.coord else: direction = vertical_line_unit_direction(args.line.start, args.line.end) self.start = args.point.coord self.end = self.start + direction case "ParallelPL": args = cast(ParallelPLArgs, self.args) self.start = args.point.coord self.end = args.point.coord + args.line.unit_direction * args.distance case _: raise NotImplementedError(f"不支持的直线构造方法: {self.construct_type}") self.length = float(np.linalg.norm(self.end - self.start)) if not close(self.length, 0): self.unit_direction = (self.end - self.start) / self.length else: self.unit_direction = np.zeros(3)