manimgeo.components.point.adapter 源代码

from __future__ import annotations

from pydantic import Field
from typing import cast
import numpy as np

from ...math import (
    axisymmetric_point,
    vertical_point_to_line,
    inversion_point,
    intersection_line_line,
    circumcenter,
    inscribed,
    orthocenter,
    point_3p_countclockwise
)
from ..base import GeometryAdapter
from .args import *

[文档] class PointAdapter(GeometryAdapter[PointConstructArgs]): coord: np.ndarray = Field(default_factory=lambda: np.zeros(3), description="计算点坐标", init=False) def __call__(self): """根据 self.args 执行具体计算""" match self.construct_type: case "Free": args = cast(FreeArgs, self.args) self.coord = args.coord case "Constraint": args = cast(ConstraintArgs, self.args) self.coord = args.coord case "MidPP": args = cast(MidPPArgs, self.args) self.coord = (args.point1.coord + args.point2.coord) / 2 case "MidL": args = cast(MidLArgs, self.args) self.coord = (args.line.start + args.line.end) / 2 case "ExtensionPP": args = cast(ExtensionPPArgs, self.args) self.coord = args.start.coord + args.factor * (args.through.coord - args.start.coord) case "AxisymmetricPL": args = cast(AxisymmetricPLArgs, self.args) self.coord = axisymmetric_point(args.point.coord, args.line.start, args.line.end) case "VerticalPL": args = cast(VerticalPLArgs, self.args) self.coord = vertical_point_to_line(args.point.coord, args.line.start, args.line.end) case "ParallelPL": args = cast(ParallelPLArgs, self.args) self.coord = args.point.coord + args.distance * args.line.unit_direction case "InversionPCir": args = cast(InversionPCirArgs, self.args) self.coord = inversion_point(args.point.coord, args.circle.center, args.circle.radius) case "IntersectionLL": args = cast(IntersectionLLArgs, self.args) result = intersection_line_line( args.line1.start, args.line1.end, args.line2.start, args.line2.end, args.line1.line_type, args.line2.line_type, args.regard_infinite ) if result is None: raise ValueError(f"两线无交点: {args.line1.name}, {args.line2.name}") else: self.coord = result case "Intersections": from .intersections import PointIntersections args = cast(IntersectionsArgs, self.args) result = PointIntersections(int_type=args.int_type)() result_num = result.num_results result_points = result.result_points if result_num == 0: raise ValueError(f"两对象无交点:{args.int_type}") elif result_num > 1: raise ValueError(f"多于一个交点的求解结果不可以 Point 类导出:{result_num} 个交点") else: self.coord = result_points[0] case "TranslationPV": args = cast(TranslationPVArgs, self.args) self.coord = args.point.coord + args.vector.vec case "CentroidPPP": args = cast(CentroidPPPArgs, self.args) self.coord = (args.point1.coord + args.point2.coord + args.point3.coord) / 3 case "CircumcenterPPP": args = cast(CircumcenterPPPArgs, self.args) _, self.coord = circumcenter( args.point1.coord, args.point2.coord, args.point3.coord ) case "IncenterPPP": args = cast(IncenterPPPArgs, self.args) _, self.coord = inscribed( args.point1.coord, args.point2.coord, args.point3.coord ) case "OrthocenterPPP": args = cast(OrthocenterPPPArgs, self.args) self.coord = orthocenter( args.point1.coord, args.point2.coord, args.point3.coord ) case "Cir": args = cast(CirArgs, self.args) self.coord = args.circle.center case "RotatePPA": args = cast(RotatePPAArgs, self.args) angle_num = args.angle.angle if args.angle.turn == 'Counterclockwise' else (2 * np.pi - args.angle.angle) axis = args.axis.vec if args.axis is not None else np.array([0, 0, 1]) self.coord = point_3p_countclockwise( args.point.coord, args.center.coord, angle_num, axis ) case _: raise NotImplementedError(f"Invalid construct type: {self.construct_type}")