模块  java.desktop
软件包  java.awt.geom

Class CubicCurve2D

  • 实现的所有接口
    Shape , Cloneable
    已知直接子类:
    CubicCurve2D.Double , CubicCurve2D.Float

    public abstract class CubicCurve2D
    extends Object
    implements Shape, Cloneable
    CubicCurve2D类在(x,y)坐标空间中定义了一个三次参数曲线段。

    此类仅是存储2D三次曲线段的所有对象的抽象超类。 坐标的实际存储表示留给子类。

    从以下版本开始:
    1.2
    • 嵌套类汇总

      嵌套类  
      变量和类型 类 描述
      static class  CubicCurve2D.Double
      用 double坐标指定的三次参数曲线段。
      static class  CubicCurve2D.Float
      用 float坐标指定的三次参数曲线段。
    • 构造方法摘要

      构造方法  
      变量 构造器 描述
      protected CubicCurve2D()
      这是一个无法直接实例化的抽象类。
    • 方法摘要

      所有方法  静态方法  实例方法 抽象方法  具体的方法 
      变量和类型 方法 描述
      Object clone()
      创建与此对象相同的类的新对象。
      boolean contains​(double x, double y)
      测试指定的坐标是否在 Shape的边界内,如 definition of insideness所述 。
      boolean contains​(double x, double y, double w, double h)
      测试 Shape的内部 Shape完全包含指定的矩形区域。
      boolean contains​(Point2D p)
      测试指定Point2D是的边界内Shape ,如所描述的definition of insideness 。
      boolean contains​(Rectangle2D r)
      测试 Shape的内部 Shape完全包含指定的 Rectangle2D 。
      Rectangle getBounds()
      返回一个整数Rectangle完全包围Shape 。
      abstract Point2D getCtrlP1()
      返回第一个控制点。
      abstract Point2D getCtrlP2()
      返回第二个控制点。
      abstract double getCtrlX1()
      以double精度返回第一个控制点的X坐标。
      abstract double getCtrlX2()
      以double精度返回第二个控制点的X坐标。
      abstract double getCtrlY1()
      以double精度返回第一个控制点的Y坐标。
      abstract double getCtrlY2()
      以double精度返回第二个控制点的Y坐标。
      double getFlatness()
      返回此曲线的平坦度。
      static double getFlatness​(double[] coords, int offset)
      返回由指定索引处的指示数组中存储的控制点指定的三次曲线的平坦度。
      static double getFlatness​(double x1, double y1, double ctrlx1, double ctrly1, double ctrlx2, double ctrly2, double x2, double y2)
      返回由指示的控制点指定的三次曲线的平坦度。
      double getFlatnessSq()
      返回此曲线平坦度的平方。
      static double getFlatnessSq​(double[] coords, int offset)
      返回由指定索引处的指示数组中存储的控制点指定的三次曲线的平坦度的平方。
      static double getFlatnessSq​(double x1, double y1, double ctrlx1, double ctrly1, double ctrlx2, double ctrly2, double x2, double y2)
      返回由指示的控制点指定的三次曲线的平坦度的平方。
      abstract Point2D getP1()
      返回起点。
      abstract Point2D getP2()
      返回结束点。
      PathIterator getPathIterator​(AffineTransform at)
      返回定义形状边界的迭代对象。
      PathIterator getPathIterator​(AffineTransform at, double flatness)
      返回定义展平形状边界的迭代对象。
      abstract double getX1()
      以double精度返回起始点的X坐标。
      abstract double getX2()
      以double精度返回结束点的X坐标。
      abstract double getY1()
      以double精度返回起始点的Y坐标。
      abstract double getY2()
      以double精度返回结束点的Y坐标。
      boolean intersects​(double x, double y, double w, double h)
      测试 Shape的内部是否与指定矩形区域的内部相交。
      boolean intersects​(Rectangle2D r)
      测试 Shape的内部是否与指定的 Rectangle2D的内部相交。
      void setCurve​(double[] coords, int offset)
      将此曲线的终点和控制点的位置设置为指定数组中指定偏移处的双坐标。
      abstract void setCurve​(double x1, double y1, double ctrlx1, double ctrly1, double ctrlx2, double ctrly2, double x2, double y2)
      将此曲线的终点和控制点的位置设置为指定的双坐标。
      void setCurve​(CubicCurve2D c)
      将此曲线的终点和控制点的位置设置为与指定的 CubicCurve2D的相同。
      void setCurve​(Point2D[] pts, int offset)
      将此曲线的终点和控制点的位置设置为指定数组中指定偏移处的 Point2D对象的坐标。
      void setCurve​(Point2D p1, Point2D cp1, Point2D cp2, Point2D p2)
      将此曲线的终点和控制点的位置设置为指定的 Point2D坐标。
      static int solveCubic​(double[] eqn)
      eqn系数在 eqn数组中的 eqn ,并将非复数根放回同一个数组中,返回根数。
      static int solveCubic​(double[] eqn, double[] res)
      求解系数在 eqn数组中的 eqn ,并将非复数根放入 res数组中,返回根数。
      static void subdivide​(double[] src, int srcoff, double[] left, int leftoff, double[] right, int rightoff)
      由索引 srcoff到( srcoff + 7)的 src数组中存储的坐标指定的三次曲线细分,并将得到的两条细分曲线存储到相应索引处的两个结果数组中。
      void subdivide​(CubicCurve2D left, CubicCurve2D right)
      细分此三次曲线并将得到的两条细分曲线存储到左右曲线参数中。
      static void subdivide​(CubicCurve2D src, CubicCurve2D left, CubicCurve2D right)
      细分由 src参数指定的三次曲线,并将得到的两条细分曲线存储到 left和 right曲线参数中。
    • 构造方法详细信息

      • CubicCurve2D

        protected CubicCurve2D()
        这是一个无法直接实例化的抽象类。 特定于类型的实现子类可用于实例化,并提供许多格式用于存储满足以下各种访问器方法所必需的信息。
        从以下版本开始:
        1.2
        另请参见:
        CubicCurve2D.Float , CubicCurve2D.Double
    • 方法详细信息

      • getX1

        public abstract double getX1()
        以double精度返回起始点的X坐标。
        结果
        CubicCurve2D起点的X坐标。
        从以下版本开始:
        1.2
      • getY1

        public abstract double getY1()
        以double精度返回起始点的Y坐标。
        结果
        CubicCurve2D起点的Y坐标。
        从以下版本开始:
        1.2
      • getP1

        public abstract Point2D getP1()
        返回起点。
        结果
        Point2D ,这是 CubicCurve2D 。
        从以下版本开始:
        1.2
      • getCtrlX1

        public abstract double getCtrlX1()
        以double精度返回第一个控制点的X坐标。
        结果
        CubicCurve2D的第一个控制点的X坐标。
        从以下版本开始:
        1.2
      • getCtrlY1

        public abstract double getCtrlY1()
        以double精度返回第一个控制点的Y坐标。
        结果
        CubicCurve2D的第一个控制点的Y坐标。
        从以下版本开始:
        1.2
      • getCtrlP1

        public abstract Point2D getCtrlP1()
        返回第一个控制点。
        结果
        一个 Point2D也就是第一个控制点 CubicCurve2D 。
        从以下版本开始:
        1.2
      • getCtrlX2

        public abstract double getCtrlX2()
        以double精度返回第二个控制点的X坐标。
        结果
        CubicCurve2D的第二个控制点的X坐标。
        从以下版本开始:
        1.2
      • getCtrlY2

        public abstract double getCtrlY2()
        以double精度返回第二个控制点的Y坐标。
        结果
        CubicCurve2D的第二个控制点的Y坐标。
        从以下版本开始:
        1.2
      • getCtrlP2

        public abstract Point2D getCtrlP2()
        返回第二个控制点。
        结果
        一个 Point2D那是的第二个控制点 CubicCurve2D 。
        从以下版本开始:
        1.2
      • getX2

        public abstract double getX2()
        以double精度返回结束点的X坐标。
        结果
        CubicCurve2D终点的X坐标。
        从以下版本开始:
        1.2
      • getY2

        public abstract double getY2()
        以double精度返回结束点的Y坐标。
        结果
        CubicCurve2D终点的Y坐标。
        从以下版本开始:
        1.2
      • getP2

        public abstract Point2D getP2()
        返回结束点。
        结果
        一个 Point2D那就是终点 CubicCurve2D 。
        从以下版本开始:
        1.2
      • setCurve

        public abstract void setCurve​(double x1,
                                      double y1,
                                      double ctrlx1,
                                      double ctrly1,
                                      double ctrlx2,
                                      double ctrly2,
                                      double x2,
                                      double y2)
        将此曲线的终点和控制点的位置设置为指定的双坐标。
        参数
        x1 - 用于设置此 CubicCurve2D起始点的X坐标
        y1 - 用于设置此 CubicCurve2D的起始点的Y坐标
        ctrlx1 - 用于设置此 CubicCurve2D的第一个控制点的X坐标
        ctrly1 - 用于设置此 CubicCurve2D的第一个控制点的Y坐标
        ctrlx2 - 用于设置此 CubicCurve2D的第二个控制点的X坐标
        ctrly2 - 用于设置此 CubicCurve2D的第二个控制点的Y坐标
        x2 - 用于设置此 CubicCurve2D的结束点的X坐标
        y2 - 用于设置此 CubicCurve2D的结束点的Y坐标
        从以下版本开始:
        1.2
      • setCurve

        public void setCurve​(double[] coords,
                             int offset)
        将此曲线的终点和控制点的位置设置为指定数组中指定偏移处的双坐标。
        参数
        coords - 包含坐标的双 coords数组
        offset - 索引 coords ,从中开始将此曲线的终点和控制点设置为 coords包含的坐标
        从以下版本开始:
        1.2
      • setCurve

        public void setCurve​(Point2D p1,
                             Point2D cp1,
                             Point2D cp2,
                             Point2D p2)
        将此曲线的终点和控制点的位置设置为指定的 Point2D坐标。
        参数
        p1 - 第一个指定的 Point2D用于设置此曲线的起点
        cp1 - 第二个指定 Point2D用于设置此曲线的第一个控制点
        cp2 - 第三个指定用于设置此曲线的第二个控制点的 Point2D
        p2 - 第四个指定的 Point2D用于设置此曲线的终点
        从以下版本开始:
        1.2
      • setCurve

        public void setCurve​(Point2D[] pts,
                             int offset)
        将此曲线的终点和控制点的位置设置为指定数组中指定偏移处的 Point2D对象的坐标。
        参数
        pts - Point2D对象的数组
        offset -的索引 pts ,从此处开始设置该曲线的点的端点和控制点包含在 pts
        从以下版本开始:
        1.2
      • setCurve

        public void setCurve​(CubicCurve2D c)
        将此曲线的终点和控制点的位置设置为与指定的 CubicCurve2D的相同。
        参数
        c - 指定的 CubicCurve2D
        从以下版本开始:
        1.2
      • getFlatnessSq

        public static double getFlatnessSq​(double x1,
                                           double y1,
                                           double ctrlx1,
                                           double ctrly1,
                                           double ctrlx2,
                                           double ctrly2,
                                           double x2,
                                           double y2)
        返回由指示的控制点指定的三次曲线的平坦度的平方。 平直度是控制点与连接端点的线的最大距离。
        参数
        x1 -的X坐标指定的起点 CubicCurve2D
        y1 - Y坐标,它指定的起点 CubicCurve2D
        ctrlx1 - 指定 CubicCurve2D的第一个控制点的X坐标
        ctrly1 - 指定 CubicCurve2D的第一个控制点的Y坐标
        ctrlx2 - 指定 CubicCurve2D的第二个控制点的X坐标
        ctrly2 - 指定 CubicCurve2D的第二个控制点的Y坐标
        x2 -的X坐标指定的结束点 CubicCurve2D
        y2 - Y坐标,它指定的结束点 CubicCurve2D
        结果
        由指定坐标表示的 CubicCurve2D的平坦度的平方。
        从以下版本开始:
        1.2
      • getFlatness

        public static double getFlatness​(double x1,
                                         double y1,
                                         double ctrlx1,
                                         double ctrly1,
                                         double ctrlx2,
                                         double ctrly2,
                                         double x2,
                                         double y2)
        返回由指示的控制点指定的三次曲线的平坦度。 平直度是控制点与连接端点的线的最大距离。
        参数
        x1 -的X坐标指定的起点 CubicCurve2D
        y1 - Y坐标,它指定的起点 CubicCurve2D
        ctrlx1 - 指定 CubicCurve2D的第一个控制点的X坐标
        ctrly1 - 指定 CubicCurve2D的第一个控制点的Y坐标
        ctrlx2 - 指定 CubicCurve2D的第二个控制点的X坐标
        ctrly2 - 指定 CubicCurve2D的第二个控制点的Y坐标
        x2 -的X坐标指定的结束点 CubicCurve2D
        y2 - 指定 CubicCurve2D的终点的Y坐标
        结果
        由指定坐标表示的 CubicCurve2D的平坦度。
        从以下版本开始:
        1.2
      • getFlatnessSq

        public static double getFlatnessSq​(double[] coords,
                                           int offset)
        返回由指定索引处的指示数组中存储的控制点指定的三次曲线的平坦度的平方。 平直度是控制点与连接端点的线的最大距离。
        参数
        coords - 包含坐标的数组
        offset - 从中获取曲线终点和控制点的 coords指数
        结果
        由指定偏移处的 coords中的坐标指定的 CubicCurve2D的平坦度的平方。
        从以下版本开始:
        1.2
      • getFlatness

        public static double getFlatness​(double[] coords,
                                         int offset)
        返回由指定索引处的指示数组中存储的控制点指定的三次曲线的平坦度。 平直度是控制点与连接端点的线的最大距离。
        参数
        coords - 包含坐标的数组
        offset -的索引 coords ,从此处开始得到曲线的端点和控制点
        结果
        CubicCurve2D的平坦度由指定偏移处的 coords中的坐标指定。
        从以下版本开始:
        1.2
      • getFlatnessSq

        public double getFlatnessSq()
        返回此曲线平坦度的平方。 平直度是控制点与连接端点的线的最大距离。
        结果
        这条曲线平坦度的平方。
        从以下版本开始:
        1.2
      • getFlatness

        public double getFlatness()
        返回此曲线的平坦度。 平直度是控制点与连接端点的线的最大距离。
        结果
        这条曲线的平坦度。
        从以下版本开始:
        1.2
      • subdivide

        public void subdivide​(CubicCurve2D left,
                              CubicCurve2D right)
        细分此三次曲线并将得到的两条细分曲线存储到左右曲线参数中。 左对象和右对象中的任何一个或两个可以与该对象相同或为null。
        参数
        left - 用于存储细分曲线的左半部分或前半部分的三次曲线对象
        right - 用于存储细分曲线的右半部分或后半部分的三次曲线对象
        从以下版本开始:
        1.2
      • subdivide

        public static void subdivide​(CubicCurve2D src,
                                     CubicCurve2D left,
                                     CubicCurve2D right)
        细分由src参数指定的三次曲线,并将得到的两条细分曲线存储到left和right曲线参数中。 left和right对象中的任何一个或两者可以与src对象或null 。
        参数
        src - 要细分的三次曲线
        left - 用于存储细分曲线的左半部分或前半部分的三次曲线对象
        right - 用于存储细分曲线的右半部分或后半部分的三次曲线对象
        从以下版本开始:
        1.2
      • subdivide

        public static void subdivide​(double[] src,
                                     int srcoff,
                                     double[] left,
                                     int leftoff,
                                     double[] right,
                                     int rightoff)
        将由存储在src数组中的坐标指定的三次曲线细分为索引srcoff到( srcoff + 7),并将得到的两条细分曲线存储到相应索引处的两个结果数组中。 left和right阵列中的任何一个或两者可以是null或对与src阵列相同的阵列的src 。 请注意,第一个细分曲线中的最后一个点与第二个细分曲线中的第一个点相同。 因此,可以为left和right传递相同的数组并使用偏移量,例如rightoff等于( leftoff + 6),以避免为此公共点分配额外的存储空间。
        参数
        src - 包含源曲线坐标的数组
        srcoff - 6个源坐标开头的数组偏移量
        left - 用于存储细分曲线前半部分坐标的数组
        leftoff - 6个左坐标开头的数组偏移量
        right - 用于存储细分曲线后半部分坐标的数组
        rightoff - 6个右坐标开头的数组偏移量
        从以下版本开始:
        1.2
      • solveCubic

        public static int solveCubic​(double[] eqn)
        eqn系数在eqn数组中的eqn ,并将非复数根返回到同一个数组中,返回根数。 求解的立方体由以下等式表示:
          eqn = {c, b, a, d}
             dx^3 + ax^2 + bx + c = 0 
        返回值-1用于区分可能始终为0或从不为0的常数方程与不具有零的方程。
        参数
        eqn - 包含立方体系数的数组
        结果
        根数,如果方程是常数,则为-1。
        从以下版本开始:
        1.2
      • solveCubic

        public static int solveCubic​(double[] eqn,
                                     double[] res)
        求解系数在eqn数组中的eqn ,并将非复数根放入res数组中,返回根数。 求解的立方体由下式表示:eqn = {c,b,a,d} dx ^ 3 + ax ^ 2 + bx + c = 0返回值-1用于区分常数方程,可以是从没有零的等式得到0或从不0。
        参数
        eqn - 用于求解三次方程的指定系数数组
        res - 包含由三次方程解得到的非复数根的数组
        结果
        根数,如果方程是常数,则为-1
        从以下版本开始:
        1.3
      • contains

        public boolean contains​(double x,
                                double y)
        测试指定的坐标是否在 Shape的边界内,如 definition of insideness所述 。
        Specified by:
        contains接口 Shape
        参数
        x - 要测试的指定X坐标
        y - 要测试的指定Y坐标
        结果
        true如果指定的坐标在Shape边界内; 否则为false 。
        从以下版本开始:
        1.2
      • contains

        public boolean contains​(Point2D p)
        测试指定Point2D是的边界内Shape ,如所描述的definition of insideness 。
        Specified by:
        contains接口 Shape
        参数
        p - 要测试的指定 Point2D
        结果
        true如果指定Point2D是的边界内Shape ; 否则为false 。
        从以下版本开始:
        1.2
      • intersects

        public boolean intersects​(double x,
                                  double y,
                                  double w,
                                  double h)
        测试Shape的内部是否与指定矩形区域的内部相交。 矩形区域被认为是交叉的Shape如果任何点被包含在双方的内部Shape和指定的矩形区域。

        Shape.intersects()方法允许Shape实现在Shape情况下保守地返回true :

        • 矩形区域与Shape交叉的概率很高,但是
        • 精确确定这个交叉点的计算非常昂贵。
        这意味着对于某些Shapes这种方法也可能返回true即使矩形区域没有相交Shape 。 Area类比大多数Shape对象执行更精确的几何交集计算,因此如果需要更精确的答案,则可以使用它。
        Specified by:
        intersects in interface Shape
        参数
        x - 指定矩形区域左上角的X坐标
        y - 指定矩形区域左上角的Y坐标
        w - 指定矩形区域的宽度
        h - 指定矩形区域的高度
        结果
        true如果Shape的内部与矩形区域的内部相交,或者两者都很可能相交并且交叉计算将太昂贵而无法执行; 否则为false 。
        从以下版本开始:
        1.2
        另请参见:
        Area
      • intersects

        public boolean intersects​(Rectangle2D r)
        测试Shape的内部是否与指定的Rectangle2D的内部相交。 Shape.intersects()方法允许Shape实现在Shape情况下保守地返回true :
        • Rectangle2D与Shape相交的概率很高,但是
        • 精确确定这个交叉点的计算非常昂贵。
        这意味着对于某些Shapes这种方法也可能返回true即使Rectangle2D不相交Shape 。 Area类比大多数Shape对象执行更精确的几何交集计算,因此如果需要更精确的答案,则可以使用它。
        Specified by:
        intersects接口 Shape
        参数
        r - 指定的 Rectangle2D
        结果
        true如果Shape的内部与指定的Rectangle2D的内部相交,或者两者都很可能相交并且交叉计算的成本太高而无法执行; 否则为false 。
        从以下版本开始:
        1.2
        另请参见:
        Shape.intersects(double, double, double, double)
      • contains

        public boolean contains​(double x,
                                double y,
                                double w,
                                double h)
        测试Shape的内部Shape完全包含指定的矩形区域。 摆在矩形区域内必须将内在于所有的坐标Shape整个矩形区域被认为包含内Shape 。

        Shape.contains()方法允许Shape实现在Shape情况下保守地返回false :

        • intersect方法返回true和
        • 用于确定Shape是否完全包含矩形区域的计算非常昂贵。
        这意味着对于某些Shapes即使Shape包含矩形区域,此方法也可能返回false 。 Area类比大多数Shape对象执行更精确的几何计算,因此如果需要更精确的答案,则可以使用它。
        Specified by:
        contains接口 Shape
        参数
        x - 指定矩形区域左上角的X坐标
        y - 指定矩形区域左上角的Y坐标
        w - 指定矩形区域的宽度
        h - 指定矩形区域的高度
        结果
        true如果内部Shape完全包含指定矩形区域; false否则,或者,如果Shape包含矩形区域并且intersects方法返回true并且包含计算将太昂贵而无法执行。
        从以下版本开始:
        1.2
        另请参见:
        Area , Shape.intersects(double, double, double, double)
      • contains

        public boolean contains​(Rectangle2D r)
        测试Shape的内部Shape完全包含指定的Rectangle2D 。 在以下情况下, Shape.contains()方法允许Shape实施保守地返回false :
        • intersect方法返回true和
        • 用于确定Shape是否完全包含Rectangle2D的计算非常昂贵。
        这意味着对于某些Shapes这种方法也可能返回false即使Shape包含Rectangle2D 。 Area类比大多数Shape对象执行更精确的几何计算,因此如果需要更精确的答案,则可以使用它。
        Specified by:
        contains接口 Shape
        参数
        r - 指定的 Rectangle2D
        结果
        true如果内部Shape完全包含Rectangle2D ; false否则,或者,如果Shape包含Rectangle2D并且intersects方法返回true并且包含计算将太昂贵而无法执行。
        从以下版本开始:
        1.2
        另请参见:
        Shape.contains(double, double, double, double)
      • getBounds

        public Rectangle getBounds()
        返回一个整数Rectangle完全包围Shape 。 请注意,不保证返回的Rectangle是最小的边框包围Shape ,只表示Shape完全在指定的范围内Rectangle 。 如果Shape溢出整数数据类型的有限范围,则返回的Rectangle也可能无法完全包含Shape 。 getBounds2D方法通常返回更严格的边界框,因为它具有更强的表示灵活性。

        请注意, definition of insideness可能会导致shape的定义轮廓上的shape可能不被视为包含在返回的bounds对象中,但仅限于原始shape不包含这些点的情况。

        如果point是内部shape根据contains(point)方法,那么它必须是内部返回Rectangle界限根据对象contains(point)所述的方法bounds 。 特别:

        shape.contains(x,y)需要bounds.contains(x,y)

        如果point不在shape ,则它可能仍包含在bounds对象中:

        bounds.contains(x,y)并不shape.contains(x,y)

        Specified by:
        getBounds接口 Shape
        结果
        整数 Rectangle ,完全包含 Shape 。
        从以下版本开始:
        1.2
        另请参见:
        Shape.getBounds2D()
      • getPathIterator

        public PathIterator getPathIterator​(AffineTransform at)
        返回定义形状边界的迭代对象。 此类的迭代器不是多线程安全的,这意味着此CubicCurve2D类不保证对此CubicCurve2D对象的几何的修改不会影响已在进行中的该几何的任何迭代。
        Specified by:
        getPathIterator接口 Shape
        参数
        at - 可选的 AffineTransform应用于迭代中返回的坐标,如果需要未转换的坐标则 null
        结果
        PathIterator对象,返回此 CubicCurve2D的轮廓几何,一次一个段。
        从以下版本开始:
        1.2
      • getPathIterator

        public PathIterator getPathIterator​(AffineTransform at,
                                            double flatness)
        返回定义展平形状边界的迭代对象。 此类的迭代器不是多线程安全的,这意味着此CubicCurve2D类不保证对此CubicCurve2D对象的几何的修改不会影响已在进行中的该几何的任何迭代。
        Specified by:
        getPathIterator in interface Shape
        参数
        at - 可选的 AffineTransform应用于迭代中返回的坐标,如果需要未转换的坐标则 null
        flatness - 在将细分曲线替换为连接端点的直线之前,给定曲线的控制点的最大量可以 flatness线变化
        结果
        PathIterator对象,返回此 CubicCurve2D的轮廓几何,一次一个段。
        从以下版本开始:
        1.2
      • clone

        public Object clone()
        创建与此对象相同的类的新对象。
        重写:
        clone类 Object
        结果
        这个实例的克隆。
        异常
        OutOfMemoryError - 如果内存不足。
        从以下版本开始:
        1.2
        另请参见:
        Cloneable