当前位置: 首页 > news >正文

8 比例缩放(scale.rs)

scale.rs代码是几何变换库euclid中典型的数据结构和方法的例子,用于处理二维和三维空间中的缩放变换。

一、scale.rs文件源码

//! A type-checked scaling factor between units.use crate::num::One;use crate::approxord::{max, min};
use crate::{Box2D, Box3D, Point2D, Point3D, Rect, Size2D, Vector2D};use core::cmp::Ordering;
use core::fmt;
use core::hash::{Hash, Hasher};
use core::marker::PhantomData;
use core::ops::{Add, Div, Mul, Sub};#[cfg(feature = "bytemuck")]
use bytemuck::{Pod, Zeroable};
use num_traits::NumCast;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};/// A scaling factor between two different units of measurement.
///
/// This is effectively a type-safe float, intended to be used in combination with other types like
/// `length::Length` to enforce conversion between systems of measurement at compile time.
///
/// `Src` and `Dst` represent the units before and after multiplying a value by a `Scale`. They
/// may be types without values, such as empty enums.  For example:
///
/// ```rust
/// use euclid::Scale;
/// use euclid::Length;
/// enum Mm {};
/// enum Inch {};
///
/// let mm_per_inch: Scale<f32, Inch, Mm> = Scale::new(25.4);
///
/// let one_foot: Length<f32, Inch> = Length::new(12.0);
/// let one_foot_in_mm: Length<f32, Mm> = one_foot * mm_per_inch;
/// ```
#[repr(C)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde",serde(bound(serialize = "T: serde::Serialize",deserialize = "T: serde::Deserialize<'de>"))
)]
pub struct Scale<T, Src, Dst>(pub T, #[doc(hidden)] pub PhantomData<(Src, Dst)>);impl<T, Src, Dst> Scale<T, Src, Dst> {#[inline]pub const fn new(x: T) -> Self {Scale(x, PhantomData)}/// 创建标识比例(1.0)#[inline]pub fn identity() -> Selfwhere T: One,{Scale::new(T::one())}/// Returns the given point transformed by this scale.////// # Example////// ```rust/// use euclid::{Scale, point2};/// enum Mm {};/// enum Cm {};////// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);////// assert_eq!(to_mm.transform_point(point2(42, -42)), point2(420, -420));/// ```#[inline]pub fn transform_point(self, point: Point2D<T, Src>) -> Point2D<T::Output, Dst>whereT: Copy + Mul,{Point2D::new(point.x * self.0, point.y * self.0)}/// Returns the given point transformed by this scale.#[inline]pub fn transform_point3d(self, point: Point3D<T, Src>) -> Point3D<T::Output, Dst>whereT: Copy + Mul,{Point3D::new(point.x * self.0, point.y * self.0, point.z * self.0)}/// Returns the given vector transformed by this scale.////// # Example////// ```rust/// use euclid::{Scale, vec2};/// enum Mm {};/// enum Cm {};////// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);////// assert_eq!(to_mm.transform_vector(vec2(42, -42)), vec2(420, -420));/// ```#[inline]pub fn transform_vector(self, vec: Vector2D<T, Src>) -> Vector2D<T::Output, Dst>whereT: Copy + Mul,{Vector2D::new(vec.x * self.0, vec.y * self.0)}/// Returns the given size transformed by this scale.////// # Example////// ```rust/// use euclid::{Scale, size2};/// enum Mm {};/// enum Cm {};////// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);////// assert_eq!(to_mm.transform_size(size2(42, -42)), size2(420, -420));/// ```#[inline]pub fn transform_size(self, size: Size2D<T, Src>) -> Size2D<T::Output, Dst>whereT: Copy + Mul,{Size2D::new(size.width * self.0, size.height * self.0)}/// Returns the given rect transformed by this scale.////// # Example////// ```rust/// use euclid::{Scale, rect};/// enum Mm {};/// enum Cm {};////// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);////// assert_eq!(to_mm.transform_rect(&rect(1, 2, 42, -42)), rect(10, 20, 420, -420));/// ```#[inline]pub fn transform_rect(self, rect: &Rect<T, Src>) -> Rect<T::Output, Dst>whereT: Copy + Mul,{Rect::new(self.transform_point(rect.origin),self.transform_size(rect.size),)}/// Returns the given box transformed by this scale.#[inline]pub fn transform_box2d(self, b: &Box2D<T, Src>) -> Box2D<T::Output, Dst>whereT: Copy + Mul,{Box2D {min: self.transform_point(b.min),max: self.transform_point(b.max),}}/// Returns the given box transformed by this scale.#[inline]pub fn transform_box3d(self, b: &Box3D<T, Src>) -> Box3D<T::Output, Dst>where T: Copy + Mul,{Box3D {min: self.transform_point3d(b.min),max: self.transform_point3d(b.max),}}/// Returns `true` if this scale has no effect.////// # Example////// ```rust/// use euclid::Scale;/// use euclid::num::One;/// enum Mm {};/// enum Cm {};////// let cm_per_mm: Scale<f32, Mm, Cm> = Scale::new(0.1);/// let mm_per_mm: Scale<f32, Mm, Mm> = Scale::new(1.0);////// assert_eq!(cm_per_mm.is_identity(), false);/// assert_eq!(mm_per_mm.is_identity(), true);/// assert_eq!(mm_per_mm, Scale::one());/// ```#[inline]pub fn is_identity(self) -> boolwhere T: PartialEq + One,{self.0 == T::one()}/// Returns the underlying scalar scale factor.#[inline]pub fn get(self) -> T {self.0}/// The inverse Scale (1.0 / self).////// # Example////// ```rust/// use euclid::Scale;/// enum Mm {};/// enum Cm {};////// let cm_per_mm: Scale<f32, Cm, Mm> = Scale::new(0.1);////// assert_eq!(cm_per_mm.inverse(), Scale::new(10.0));/// ```pub fn inverse(self) -> Scale<T::Output, Dst, Src>whereT: One + Div,{let one: T = One::one();Scale::new(one / self.0)}
}impl<T: PartialOrd, Src, Dst> Scale<T, Src, Dst> {#[inline]pub fn min(self, other: Self) -> Self {Self::new(min(self.0, other.0))}#[inline]pub fn max(self, other: Self) -> Self {Self::new(max(self.0, other.0))}/// Returns the point each component of which clamped by corresponding/// components of `start` and `end`.////// Shortcut for `self.max(start).min(end)`.#[inline]pub fn clamp(self, start: Self, end: Self) -> SelfwhereT: Copy,{self.max(start).min(end)}
}impl<T: NumCast, Src, Dst> Scale<T, Src, Dst> {/// Cast from one numeric representation to another, preserving the units.////// # Panics////// If the source value cannot be represented by the target type `NewT`, then/// method panics. Use `try_cast` if that must be case.////// # Example////// ```rust/// use euclid::Scale;/// enum Mm {};/// enum Cm {};////// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);////// assert_eq!(to_mm.cast::<f32>(), Scale::new(10.0));/// ```/// That conversion will panic, because `i32` not enough to store such big numbers:/// ```rust,should_panic/// use euclid::Scale;/// enum Mm {};// millimeter = 10^-2 meters/// enum Em {};// exameter   = 10^18 meters////// // Panics/// let to_em: Scale<i32, Mm, Em> = Scale::new(10e20).cast();/// ```#[inline]pub fn cast<NewT: NumCast>(self) -> Scale<NewT, Src, Dst> {self.try_cast().unwrap()}/// Fallible cast from one numeric representation to another, preserving the units./// If the source value cannot be represented by the target type `NewT`, then `None`/// is returned.////// # Example////// ```rust/// use euclid::Scale;/// enum Mm {};/// enum Cm {};/// enum Em {};// Exameter = 10^18 meters////// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);/// let to_em: Scale<f32, Mm, Em> = Scale::new(10e20);////// assert_eq!(to_mm.try_cast::<f32>(), Some(Scale::new(10.0)));/// // Integer to small to store that number/// assert_eq!(to_em.try_cast::<i32>(), None);/// ```pub fn try_cast<NewT: NumCast>(self) -> Option<Scale<NewT, Src, Dst>> {NumCast::from(self.0).map(Scale::new)}
}#[cfg(feature = "arbitrary")]
impl<'a, T, Src, Dst> arbitrary::Arbitrary<'a> for Scale<T, Src, Dst>
whereT: arbitrary::Arbitrary<'a>,
{fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {Ok(Scale::new(arbitrary::Arbitrary::arbitrary(u)?))}
}#[cfg(feature = "bytemuck")]
unsafe impl<T: Zeroable, Src, Dst> Zeroable for Scale<T, Src, Dst> {}#[cfg(feature = "bytemuck")]
unsafe impl<T: Pod, Src: 'static, Dst: 'static> Pod for Scale<T, Src, Dst> {}// scale0 * scale1
// (A,B) * (B,C) = (A,C)
impl<T: Mul, A, B, C> Mul<Scale<T, B, C>> for Scale<T, A, B> {type Output = Scale<T::Output, A, C>;#[inline]fn mul(self, other: Scale<T, B, C>) -> Self::Output {Scale::new(self.0 * other.0)}
}// scale0 + scale1
impl<T: Add, Src, Dst> Add for Scale<T, Src, Dst> {type Output = Scale<T::Output, Src, Dst>;#[inline]fn add(self, other: Scale<T, Src, Dst>) -> Self::Output {Scale::new(self.0 + other.0)}
}// scale0 - scale1
impl<T: Sub, Src, Dst> Sub for Scale<T, Src, Dst> {type Output = Scale<T::Output, Src, Dst>;#[inline]fn sub(self, other: Scale<T, Src, Dst>) -> Self::Output {Scale::new(self.0 - other.0)}
}// FIXME: Switch to `derive(PartialEq, Clone)` after this Rust issue is fixed:
// https://github.com/rust-lang/rust/issues/26925impl<T: PartialEq, Src, Dst> PartialEq for Scale<T, Src, Dst> {fn eq(&self, other: &Scale<T, Src, Dst>) -> bool {self.0 == other.0}
}impl<T: Eq, Src, Dst> Eq for Scale<T, Src, Dst> {}impl<T: PartialOrd, Src, Dst> PartialOrd for Scale<T, Src, Dst> {fn partial_cmp(&self, other: &Self) -> Option<Ordering> {self.0.partial_cmp(&other.0)}
}impl<T: Ord, Src, Dst> Ord for Scale<T, Src, Dst> {fn cmp(&self, other: &Self) -> Ordering {self.0.cmp(&other.0)}
}impl<T: Clone, Src, Dst> Clone for Scale<T, Src, Dst> {fn clone(&self) -> Scale<T, Src, Dst> {Scale::new(self.0.clone())}
}impl<T: Copy, Src, Dst> Copy for Scale<T, Src, Dst> {}impl<T: fmt::Debug, Src, Dst> fmt::Debug for Scale<T, Src, Dst> {fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {self.0.fmt(f)}
}impl<T: Default, Src, Dst> Default for Scale<T, Src, Dst> {fn default() -> Self {Self::new(T::default())}
}impl<T: Hash, Src, Dst> Hash for Scale<T, Src, Dst> {fn hash<H: Hasher>(&self, state: &mut H) {self.0.hash(state);}
}impl<T: One, Src, Dst> One for Scale<T, Src, Dst> {#[inline]fn one() -> Self {Scale::new(T::one())}
}#[cfg(test)]
mod tests {use super::Scale;enum Inch {}enum Cm {}enum Mm {}#[test]fn test_scale() {let mm_per_inch: Scale<f32, Inch, Mm> = Scale::new(25.4);let cm_per_mm: Scale<f32, Mm, Cm> = Scale::new(0.1);let mm_per_cm: Scale<f32, Cm, Mm> = cm_per_mm.inverse();assert_eq!(mm_per_cm.get(), 10.0);let one: Scale<f32, Mm, Mm> = cm_per_mm * mm_per_cm;assert_eq!(one.get(), 1.0);let one: Scale<f32, Cm, Cm> = mm_per_cm * cm_per_mm;assert_eq!(one.get(), 1.0);let cm_per_inch: Scale<f32, Inch, Cm> = mm_per_inch * cm_per_mm;//  mm     cm     cm// ---- x ---- = ----// inch    mm    inchassert_eq!(cm_per_inch, Scale::new(2.54));let a: Scale<isize, Inch, Inch> = Scale::new(2);let b: Scale<isize, Inch, Inch> = Scale::new(3);assert_ne!(a, b);assert_eq!(a, a.clone());assert_eq!(a.clone() + b.clone(), Scale::new(5));assert_eq!(a - b, Scale::new(-1));// Clampassert_eq!(Scale::identity().clamp(a, b), a);assert_eq!(Scale::new(5).clamp(a, b), b);let a = Scale::<f32, Inch, Inch>::new(2.0);let b = Scale::<f32, Inch, Inch>::new(3.0);let c = Scale::<f32, Inch, Inch>::new(2.5);assert_eq!(c.clamp(a, b), c);}
}

二、结构体定义

#[repr(C)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde",serde(bound(serialize = "T: serde::Serialize",deserialize = "T: serde::Deserialize<'de>"))
)]
pub struct Scale<T, Src, Dst>(pub T, #[doc(hidden)] pub PhantomData<(Src, Dst)>);

上面代码定义了一个使用Rust语言特性的泛型结构体Scale,这个结构体不仅使用了Rust的条件编译指令,还考虑了序列化/反序列化的能力,如果项目中启用了serde特性。下面是对这段代码的详细解释:

  1. #[repr( C )]:这个属性指定了结构体应该使用C语言的布局规则。这意味着结构体的内存布局将与C语言中的等效结构相匹配,这对于与C语言代码交互或与需要特定内存布局的系统API交互非常有用。
  2. #[cfg_attr(feature = “serde”, derive(Serialize, Deserialize))]:这是条件编译属性的一个示例。如果项目配置了serde特性(通常在Cargo.toml文件中通过features部分指定),那么将为这个结构体派生Serialize和Deserialize特性。这两个特性来自serde库,允许结构体实例被序列化为JSON、RON等格式或从这些格式反序列化。
  3. #[cfg_attr(… serde(bound(…)) )]:这部分进一步细化了serde特性的条件编译。它指定了当序列化或反序列化时,泛型参数T必须满足的条件。具体来说,如果正在序列化,T必须实现serde::Serialize;如果正在反序列化,T必须实现serde::Deserialize<'de>。这里,'de是一个生命周期参数,它是反序列化过程中使用的,表明反序列化操作与特定数据的生命周期相关联。
  4. pub struct Scale<T, Src, Dst>(pub T, #[doc(hidden)] pub PhantomData<(Src, Dst)>);:这是Scale结构体的定义。它是一个泛型结构体,有三个类型参数:T、Src和Dst。结构体内部包含两个字段:
  • 第一个字段是公开的(pub T),意味着它可以被外部访问。
  • 第二个字段是PhantomData<(Src, Dst)>,它被标记为#[doc(hidden)],意味着在生成的文档中这个字段将被隐藏。PhantomData是一个特殊的类型,用于在类型系统中表达所有权、借用或生命周期,但不占用任何运行时空间。在这里,它用于表示Scale结构体与Src和Dst类型有关联,尽管这两个类型在运行时并不实际存储任何数据。
  1. 总结:这段代码定义了一个条件编译支持序列化/反序列化,同时遵循C语言内存布局规则的泛型结构体,用于在Rust代码中表示某种形式的缩放或转换操作,其中T代表缩放或转换的值类型,而Src和Dst则用于在类型系统中表达源和目标类型的信息。

三、对应方法

方法源码

impl<T, Src, Dst> Scale<T, Src, Dst> {#[inline]pub const fn new(x: T) -> Self {Scale(x, PhantomData)}/// 创建标识比例(1.0)#[inline]pub fn identity() -> Selfwhere T: One,{Scale::new(T::one())}/// Returns the given point transformed by this scale.////// # Example////// ```rust/// use euclid::{Scale, point2};/// enum Mm {};/// enum Cm {};////// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);////// assert_eq!(to_mm.transform_point(point2(42, -42)), point2(420, -420));/// ```#[inline]pub fn transform_point(self, point: Point2D<T, Src>) -> Point2D<T::Output, Dst>whereT: Copy + Mul,{Point2D::new(point.x * self.0, point.y * self.0)}/// Returns the given point transformed by this scale.#[inline]pub fn transform_point3d(self, point: Point3D<T, Src>) -> Point3D<T::Output, Dst>whereT: Copy + Mul,{Point3D::new(point.x * self.0, point.y * self.0, point.z * self.0)}/// Returns the given vector transformed by this scale.////// # Example////// ```rust/// use euclid::{Scale, vec2};/// enum Mm {};/// enum Cm {};////// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);////// assert_eq!(to_mm.transform_vector(vec2(42, -42)), vec2(420, -420));/// ```#[inline]pub fn transform_vector(self, vec: Vector2D<T, Src>) -> Vector2D<T::Output, Dst>whereT: Copy + Mul,{Vector2D::new(vec.x * self.0, vec.y * self.0)}/// Returns the given size transformed by this scale.////// # Example////// ```rust/// use euclid::{Scale, size2};/// enum Mm {};/// enum Cm {};////// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);////// assert_eq!(to_mm.transform_size(size2(42, -42)), size2(420, -420));/// ```#[inline]pub fn transform_size(self, size: Size2D<T, Src>) -> Size2D<T::Output, Dst>whereT: Copy + Mul,{Size2D::new(size.width * self.0, size.height * self.0)}/// Returns the given rect transformed by this scale.////// # Example////// ```rust/// use euclid::{Scale, rect};/// enum Mm {};/// enum Cm {};////// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);////// assert_eq!(to_mm.transform_rect(&rect(1, 2, 42, -42)), rect(10, 20, 420, -420));/// ```#[inline]pub fn transform_rect(self, rect: &Rect<T, Src>) -> Rect<T::Output, Dst>whereT: Copy + Mul,{Rect::new(self.transform_point(rect.origin),self.transform_size(rect.size),)}/// Returns the given box transformed by this scale.#[inline]pub fn transform_box2d(self, b: &Box2D<T, Src>) -> Box2D<T::Output, Dst>whereT: Copy + Mul,{Box2D {min: self.transform_point(b.min),max: self.transform_point(b.max),}}/// Returns the given box transformed by this scale.#[inline]pub fn transform_box3d(self, b: &Box3D<T, Src>) -> Box3D<T::Output, Dst>where T: Copy + Mul,{Box3D {min: self.transform_point3d(b.min),max: self.transform_point3d(b.max),}}/// Returns `true` if this scale has no effect.////// # Example////// ```rust/// use euclid::Scale;/// use euclid::num::One;/// enum Mm {};/// enum Cm {};////// let cm_per_mm: Scale<f32, Mm, Cm> = Scale::new(0.1);/// let mm_per_mm: Scale<f32, Mm, Mm> = Scale::new(1.0);////// assert_eq!(cm_per_mm.is_identity(), false);/// assert_eq!(mm_per_mm.is_identity(), true);/// assert_eq!(mm_per_mm, Scale::one());/// ```#[inline]pub fn is_identity(self) -> boolwhere T: PartialEq + One,{self.0 == T::one()}/// Returns the underlying scalar scale factor.#[inline]pub fn get(self) -> T {self.0}/// The inverse Scale (1.0 / self).////// # Example////// ```rust/// use euclid::Scale;/// enum Mm {};/// enum Cm {};////// let cm_per_mm: Scale<f32, Cm, Mm> = Scale::new(0.1);////// assert_eq!(cm_per_mm.inverse(), Scale::new(10.0));/// ```pub fn inverse(self) -> Scale<T::Output, Dst, Src>whereT: One + Div,{let one: T = One::one();Scale::new(one / self.0)}
}

2、new 方法:

这是一个常量函数,用于创建一个新的 Scale 实例。它接受一个类型为 T 的参数 x 作为缩放因子。

3、identity 方法:

用于创建一个表示没有缩放的 Scale 实例(即缩放因子为 1.0)。这需要 T 类型实现 One trait,该 trait 提供了一个获取类型中“1”的方法。

4、transform_point 方法:

用于将二维点(Point2D<T, Src>)根据缩放因子变换到新的单位系统(Dst)。这个方法要求 T 类型实现 Copy 和 Mul traits,以便可以复制和乘法操作。

5、transform_point3d 方法:

类似于 transform_point,但是用于三维点(Point3D<T, Src>)。

6、is_identity 方法:

检查当前的缩放因子是否为 1.0(即是否没有缩放)。这要求 T 类型实现 PartialEq 和 One traits。

7、get 方法:

返回缩放因子 x。

8、inverse 方法:

返回当前缩放的逆缩放,即将 1.0 / self.0 作为新的缩放因子。这要求 T 类型实现 One 和 Div traits。

9、min和max方法的实现:

min和max方法分别返回两个Scale实例之间较小或较大的那个。它们使用内部存储的值(self.0)来调用标准库中的min和max函数。

10、clamp方法的实现:

clamp方法将当前Scale实例的每个分量限制在start和end指定的范围内。这是通过先对start使用max方法,然后对end使用min方法来实现的,从而确保结果位于start和end之间。

11、NumCast trait相关的实现:

这部分代码被注释掉了,似乎原本打算为Scale实现一个与数值类型转换相关的功能,允许从一种数值表示转换到另一种,但具体的实现被省略了。

12、partial_cmp、cmp方法的实现:

  • partial_cmp方法提供了一个可选的比较结果,这在类型T只能部分排序时非常有用(例如,浮点数与NaN的比较)。
  • cmp方法提供了一个确定性的比较结果,要求T必须完全可排序(实现Ord trait)。

13、Clone、Copy trait的实现:

为Scale实现了Clone和Copy trait,这取决于T是否也实现了这些trait。如果T可以克隆或复制,那么Scale<T, Src, Dst>也可以。

14、Debug trait的实现:

为Scale实现了Debug trait,允许其实例使用{:?}格式化时打印调试信息。这依赖于T也实现了Debug trait。

15、Default trait的实现:

为Scale实现了Default trait,提供了一个默认构造函数,它依赖于T也实现了Default trait。

16、Hash trait的实现:

为Scale实现了Hash trait,允许其实例被哈希。这依赖于T也实现了Hash trait。

17、One trait的实现:

为Scale实现了One trait,提供了一个单位元素的构造函数(即值为1的Scale实例)。这依赖于T也实现了One trait。

相关文章:

8 比例缩放(scale.rs)

scale.rs代码是几何变换库euclid中典型的数据结构和方法的例子&#xff0c;用于处理二维和三维空间中的缩放变换。 一、scale.rs文件源码 //! A type-checked scaling factor between units.use crate::num::One;use crate::approxord::{max, min}; use crate::{Box2D, Box3D…...

二分 机器人的跳跃问题

二段性:找到一个值&#xff0c;大于此值的时候都成立&#xff0c;小于的时候都不成立 更新的方式只有两种&#xff0c;左边的mid更新不需要1&#xff1b;右边的mid更新需要1 //对能量进行二分&#xff0c;确定能量的范围 //特判防止溢出int #include<bits/stdc.h> using…...

Hive:复杂数据类型之Map函数

Map函数 是Hive里面的一种复杂数据类型, 用于存储键值对集合。Map中的键和值可以是基础类型或复合类型&#xff0c;这使得Map在处理需要关联存储信息的数据时非常有用。 定义map时,需声明2个属性: key 和 value , map中是 key value 组成一个元素 key-value, key必须为原始类…...

R 字符串:深入理解与高效应用

R 字符串:深入理解与高效应用 引言 在R语言中,字符串是数据处理和编程中不可或缺的一部分。无论是数据清洗、数据转换还是数据分析,字符串的处理都是基础技能。本文将深入探讨R语言中的字符串概念,包括其基本操作、常见函数以及高效应用方法。 字符串基本概念 字符串定…...

设计模式Python版 桥接模式

文章目录 前言一、桥接模式二、桥接模式示例三、桥接模式与适配器模式的联用 前言 GOF设计模式分三大类&#xff1a; 创建型模式&#xff1a;关注对象的创建过程&#xff0c;包括单例模式、简单工厂模式、工厂方法模式、抽象工厂模式、原型模式和建造者模式。结构型模式&…...

记5(一元逻辑回归+线性分类器+多元逻辑回归

目录 1、一元逻辑回归2、线性可分&线性不可分3、Iris数据集实现多元逻辑回归4、绘制分类图5、鸢尾花分类图6、多分类问题&#xff1a;&#xff08;softmax回归&#xff09;6.1、编码&#xff1a;自然顺序码、独热编码、独冷编码6.2、二/多分类问题&#xff1a;6.3、softmax…...

【Python】第七弹---Python基础进阶:深入字典操作与文件处理技巧

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】【MySQL】【Python】 目录 1、字典 1.1、字典是什么 1.2、创建字典 1.3、查找 key 1.4、新增/修改元素 1.5、删除元素 1.6、遍历…...

Nginx 运维开发高频面试题详解

一、基础核心问题 原文链接&#xff1a;https://blog.csdn.net/weixin_51146329/article/details/142963853 1、什么是Nginx&#xff1f; Nginx 是一个高性能的 HTTP 和反向代理服务器&#xff0c;它以轻量级和高并发处理能力而闻名。Nginx 的反向代理功能允许它作为前端服务…...

下载OpenJDK

由于Oracle需要付费&#xff0c;并且之前我在寻找openJDK的时候&#xff0c;我不知道网址&#xff0c;并且也不知道在这个openjdk这个网址里点击哪个模块进行下载。最近我在看虚拟机相关的书籍的时候&#xff0c;找到了相关的网址。 注意&#xff1a;下面的下载都是基于可以科…...

Web3.js详解

Web1&Web2&Web3 以下是Web1、Web2和Web3的详细介绍&#xff0c;以及一个对比表格&#xff1a; Web1 定义&#xff1a;Web1指的是有着固定内容的非许可的开源网络。特点&#xff1a;在Web1时代&#xff0c;网站内容主要由网站管理员或创建者提供&#xff0c;用户只能…...

学习串行通信

本文来源&#xff1a; [8-1] 串口通信_哔哩哔哩_bilibili 智谱清言 ------------ 串口&#xff08;Serial Port&#xff09;&#xff1a; 串口是一种应用非常广泛的通讯接口&#xff0c;串口成本低&#xff0c;容易使用&#xff0c;通信线路简单&#xff0c;可实现两个设…...

【leetcode强化练习·二叉树】同时运用两种思维解题

本文参考labuladong算法笔记[【强化练习】同时运用两种思维解题 | labuladong 的算法笔记] 有的题目可以同时用「遍历」和「分解问题」两种思路来解&#xff0c;你可以利用这些题目训练自己的思维。 559. N 叉树的最大深度 | 力扣 | LeetCode | 给定一个 N 叉树&#xff0c;…...

Rank-analysis-1.2——一款基于LCU API的排位分析工具,大四学生独立开发

LOL Rank Record Analysis&#xff1a;一款基于LCU API的排位分析工具&#xff0c;大四学生独立开发&#xff01; 大家好&#xff01;我是河南科技学院的大四学生&#xff0c;今天给大家分享一个我自己开发的软件——LOL Rank Record Analysis。这是一个基于 Riot 提供的 LCU …...

什么是门控循环单元?

一、概念 门控循环单元&#xff08;Gated Recurrent Unit&#xff0c;GRU&#xff09;是一种改进的循环神经网络&#xff08;RNN&#xff09;&#xff0c;由Cho等人在2014年提出。GRU是LSTM的简化版本&#xff0c;通过减少门的数量和简化结构&#xff0c;保留了LSTM的长时间依赖…...

Google Chrome-便携增强版[解压即用]

Google Chrome-便携增强版 链接&#xff1a;https://pan.xunlei.com/s/VOI0OyrhUx3biEbFgJyLl-Z8A1?pwdf5qa# a 特点描述 √ 无升级、便携式、绿色免安装&#xff0c;即可以覆盖更新又能解压使用&#xff01; √ 此增强版&#xff0c;支持右键解压使用 √ 加入Chrome增强…...

智慧园区综合管理系统如何实现多个维度的高效管理与安全风险控制

内容概要 在当前快速发展的城市环境中&#xff0c;智慧园区综合管理系统正在成为各类园区管理的重要工具&#xff0c;无论是工业园、产业园、物流园&#xff0c;还是写字楼与公寓&#xff0c;都在积极寻求如何提升管理效率和保障安全。通过快鲸智慧园区管理系统&#xff0c;用…...

【PyTorch】7.自动微分模块:开启神经网络 “进化之门” 的魔法钥匙

目录 1. 梯度基本计算 2. 控制梯度计算 3. 梯度计算注意 4. 小节 个人主页&#xff1a;Icomi 专栏地址&#xff1a;PyTorch入门 在深度学习蓬勃发展的当下&#xff0c;PyTorch 是不可或缺的工具。它作为强大的深度学习框架&#xff0c;为构建和训练神经网络提供了高效且灵活…...

从0开始使用面对对象C语言搭建一个基于OLED的图形显示框架(协议层封装)

目录 协议层设计&#xff0c;以IIC为例子 关于软硬件IIC 设计的一些原则 完成协议层的抽象 刨析我们的原理 如何完成我们的抽象 插入几个C语言小技巧 完成软件IIC通信 开始我们的IIC通信 结束我们的IIC通信 发送一个字节 &#xff08;重要&#xff09;完成命令传递和…...

Mac M1 源码安装FFmpeg,开启enable-gpl 和 lib x264

1、第一步&#xff1a;下载并安装minicoda curl -O https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-arm64.shsh Miniconda3-latest-MacOSX-arm64.sh2、第二步&#xff1a;安装必要的依赖 conda install -c conda-forge gcc make nasm yasm3、第三步&#xff…...

【Quest开发】手柄单手抓握和双手抓握物体切换

V72更新以后非常智能哈&#xff0c;配置物体简单多了。 选择需要被抓取的物体鼠标右键单击它&#xff0c;点Add Grab Interaction&#xff0c;按它要求的配置就行 配好以后长这样 把这个选项取消勾选就能切换成双手抓一个物体了&#xff0c;不需要像以前一样用各种grabTransfo…...

DB-GPT试用

继续上一篇 DB-GPT的安装 https://blog.csdn.net/berryreload/article/details/142845190 访问http://xxx:5670 访问这里 创建数据库连接 http://10.168.1.208:5670/construct/database 访问这里&#xff0c;点击刷新 http://10.168.1.208:5670/construct/app 刷新后才能出…...

​《Ollama Python 库​》

Ollama Python 库 Ollama Python 库提供了将 Python 3.8 项目与 Ollama 集成的最简单方法。 先决条件 应该安装并运行 Ollama拉取一个模型以与库一起使用&#xff1a;例如ollama pull <model>ollama pull llama3.2 有关可用模型的更多信息&#xff0c;请参阅 Ollama.com。…...

Java的Integer缓存池

Java的Integer缓冲池&#xff1f; Integer 缓存池主要为了提升性能和节省内存。根据实践发现大部分的数据操作都集中在值比较小的范围&#xff0c;因此缓存这些对象可以减少内存分配和垃圾回收的负担&#xff0c;提升性能。 在-128到 127范围内的 Integer 对象会被缓存和复用…...

Ubuntu16.04编译安装Cartographer 1.0版本

说明 官方文档 由于Ubuntu16.04已经是很老的系统&#xff0c;如果直接按照Cartographer官方安装文档安装会出现代码编译失败的问题&#xff0c;本文给出了解决这些问题的办法。正常情况下执行本文给出的安装方法即可成功安装。 依赖安装 # 这里和官方一致 # Install the req…...

Qt调用FFmpeg库实时播放UDP组播视频流

基于以下参考链接&#xff0c;通过改进实现实时播放UDP组播视频流 https://blog.csdn.net/u012532263/article/details/102736700 源码在windows&#xff08;qt-opensource-windows-x86-5.12.9.exe&#xff09;、ubuntu20.04.6(x64)(qt-opensource-linux-x64-5.12.12.run)、以…...

C# 类与对象详解

.NET学习资料 .NET学习资料 .NET学习资料 在 C# 编程中&#xff0c;类与对象是面向对象编程的核心概念。它们让开发者能够将数据和操作数据的方法封装在一起&#xff0c;从而构建出模块化、可维护且易于扩展的程序。下面将详细介绍 C# 中类与对象的相关知识。 一、类的定义 …...

【Elasticsearch 基础入门】Centos7下Elasticsearch 7.x安装与配置(单机)

Elasticsearch系列文章目录 【Elasticsearch 基础入门】一文带你了解Elasticsearch&#xff01;&#xff01;&#xff01;【Elasticsearch 基础入门】Centos7下Elasticsearch 7.x安装与配置&#xff08;单机&#xff09; 目录 Elasticsearch系列文章目录前言单机模式1. 安装 J…...

大模型本地部署使用方法(Ollama脚手架工具、FisherAI浏览器大模型插件、AnythingLLM大模型集成应用平台)

一、Ollama &#xff08;一&#xff09;Ollama简介 Ollama是一个专为在本地环境中运行和定制大型语言模型而设计的工具。它提供简单高效的接口&#xff0c;用于创建、运行和管理这些模型&#xff0c;方便用户直接使用&#xff0c;也方便用作后台服务支撑其它应用程序。熟悉网…...

【华为OD-E卷 - 报数游戏 100分(python、java、c++、js、c)】

【华为OD-E卷 - 报数游戏 100分&#xff08;python、java、c、js、c&#xff09;】 题目 100个人围成一圈&#xff0c;每个人有一个编码&#xff0c;编号从1开始到100。 他们从1开始依次报数&#xff0c;报到为M的人自动退出圈圈&#xff0c;然后下一个人接着从1开始报数&…...

深入理解Spring框架:从基础到实践

前言 Spring框架是一个开源的企业级应用开发框架&#xff0c;它为Java开发者提供了灵活的架构支持&#xff0c;特别是在依赖注入&#xff08;IOC&#xff09;和面向切面编程&#xff08;AOP&#xff09;方面。本文将通过具体的示例&#xff0c;带你从Spring框架的概述、IOC容器…...