Source code for pythagoras.r3.sphere

from dataclasses import dataclass

from ..backend import fill_default_args, svg_command, tikz_command
from ..pobject import POProperty, RenderingContext
from ..style import CustomStyle
from ..style.color import BLACK
from ..style.draw import Fill, LineWidth, Stroke
from ..utils import cartesian_to_canvas
from .camera import Camera3D
from .pobject import PObject3D
from .rendering import project_point

__all__ = ["FakeSphere"]


[docs] @dataclass(init=False) class FakeSphere(PObject3D): r""" Circle centered in a point in :math:`\mathbf R^3` which emulates a sphere. Attributes: center: Center of the fake sphere. radius: Radius of the fake sphere. """ center: tuple[float, float, float] radius: float def __init__( self, center: tuple[float, float, float], radius: float, zord: int = 0 ) -> None: self.center = center self.radius = radius self._zord = zord
[docs] def visible_radius(self, camera: Camera3D, frustum: float) -> float: """ Compute the radius of the sphere from the perspective of the camera. Returns: Radius from that angle. """ return self.radius * frustum / (self.center[2] - camera.position[2])
[docs] def svg( self, camera: Camera3D, frustum: float, width: float, height: float, scale: float, lights: list[tuple[tuple[float, float, float], float]], *args: POProperty, ) -> str: _pc = project_point(camera, frustum, self.center) if not _pc: return "" cx, cy = cartesian_to_canvas( _pc, RenderingContext.from_dimensions(scale, width, height) ) vr = self.visible_radius(camera, frustum) * scale args = ( CustomStyle("cx", cx), CustomStyle("cy", cy), CustomStyle("r", vr), *args, ) return svg_command( "circle", *fill_default_args( args, (Fill, Fill(None)), (Stroke, Stroke(BLACK)), (LineWidth, LineWidth(vr / 20)), ), )
[docs] def tikz( self, camera: Camera3D, frustum: float, lights: list[tuple[tuple[float, float, float], float]], *args: POProperty, ) -> str: p = project_point(camera, frustum, self.center) if not p: return "" cmd = "filldraw" if any(isinstance(x, Fill) for x in args) else "draw" return tikz_command( cmd, f"({p[0]}, {p[1]}) circle ({self.visible_radius(camera, frustum)})", *args, )