Esempio n. 1
0
RH_C_FUNCTION int ON_RayShooter_OneSurface(ON_3DPOINT_STRUCT _point, ON_3DVECTOR_STRUCT _direction, const ON_Surface* pConstSurface, ON_SimpleArray<ON_3dPoint>* pPoints, int maxReflections)
{
  int rc = 0;
  ON_3dPoint point(_point.val[0], _point.val[1], _point.val[2]);
  ON_3dVector direction(_direction.val[0], _direction.val[1], _direction.val[2]);
  if( pConstSurface && pPoints && maxReflections>0 && point.IsValid() && direction.Unitize() )
  {
    ON_RayShooter shooter;
    ON_X_EVENT hit;
    ON_3dPoint Q = point;
    ON_3dVector R = direction;
    ON_3dVector V[3];
    for( int i=0; i<maxReflections; i++ )
    {
      memset(&hit,0,sizeof(hit));
      ON_3dVector T = R;
      if( !T.Unitize() )
        break;
      if( !shooter.Shoot(Q,T,pConstSurface,hit) )
        break;
      Q = hit.m_A[0];
      pPoints->Append(Q);
      if( !hit.m_snodeB[0] )
        break;
      hit.m_snodeB[0]->Evaluate(hit.m_b[0], hit.m_b[1], 1, 3, &V[0].x);
      ON_3dVector N = ON_CrossProduct(V[1],V[2]);
      if ( !N.Unitize() )
        break;
      double d = N*T;
      R = T + (-2.0*d)*N; // R = reflection direction
    }
    rc = pPoints->Count();
  }
  return rc;
}
Esempio n. 2
0
int ON_Box::IsDegenerate( double tolerance ) const
{
  int rc = 0;
  // 0     box is not degenerate
  // 1     box is a rectangle (degenerate in one direction)
  // 2     box is a line (degenerate in two directions)
  // 3     box is a point (degenerate in three directions)
  // 4     box is not valid
  if ( !dx.IsIncreasing() || !dy.IsIncreasing() || !dz.IsIncreasing() )
  {
    rc = 4;
  }
  else
  {
    const ON_3dVector diag(dx.Length(),dy.Length(),dz.Length());
    if ( !ON_IsValid(tolerance) || tolerance < 0.0 )
    {
      // compute scale invarient tolerance
      tolerance = diag.MaximumCoordinate()*ON_SQRT_EPSILON;
    }
    if ( diag.x <= tolerance )
      rc++;
    if ( diag.y <= tolerance )
      rc++;
    if ( diag.z <= tolerance )
      rc++;
  }
  return rc;
}
Esempio n. 3
0
ON_BOOL32 ON_Light::Transform( 
       const ON_Xform& xform
       )
{
  ON_3dVector v;
  double vlen;
  TransformUserData(xform);
  m_location = xform*m_location;
  
  v = xform*m_direction;
  vlen = v.Length();
  if ( vlen > 0.0 ) {
    m_direction = v;
  }
  
  v = xform*m_length;
  vlen = v.Length();
  if ( vlen > 0.0 ) {
    m_length = v;
  }
  
  v = xform*m_width;
  vlen = v.Length();
  if ( vlen > 0.0 ) {
    m_width = v;
  }
  return true;
}
CRhinoCommand::result CCommandSampleMoveCPlane::RunCommand( const CRhinoCommandContext& context )
{
  CRhinoView* view = ::RhinoApp().ActiveView();
  if( !view )
    return CRhinoCommand::failure;

  ON_3dmConstructionPlane cplane = view->Viewport().ConstructionPlane();
  ON_3dPoint origin = cplane.m_plane.origin;

  CSampleMoveCPlanePoint gp( cplane );
  gp.SetCommandPrompt( L"CPlane origin" );
  gp.SetBasePoint( origin );
  gp.DrawLineFromPoint( origin, TRUE );
  gp.GetPoint();

  if( gp.CommandResult() != CRhinoCommand::success )
    return gp.CommandResult();

  ON_3dPoint pt = gp.Point();
  ON_3dVector v = origin - pt;
  if( v.IsTiny() )
    return CRhinoCommand::nothing;

  cplane.m_plane.CreateFromFrame( pt, cplane.m_plane.xaxis, cplane.m_plane.yaxis );
  view->Viewport().SetConstructionPlane( cplane );
  view->Redraw();

	return CRhinoCommand::success;
}
Esempio n. 5
0
ON_BOOL32 ON_ArcCurve::SetStartPoint(ON_3dPoint start_point)
{
  if (IsCircle())
    return false;
  ON_BOOL32 rc = false;
  if ( m_dim == 3 || start_point.z == 0.0 )
  {
    ON_3dPoint P;
    ON_3dVector T;
    double t = Domain()[1];
    Ev1Der( t, P, T );
    T.Reverse();
    ON_Arc a;
    rc = a.Create( P, T, start_point );
    if ( rc )
    {
      a.Reverse();
      m_arc = a;
    }
    else {
      ON_3dPoint end_point = PointAt(Domain()[1]);
      if (end_point.DistanceTo(start_point) < ON_ZERO_TOLERANCE*m_arc.Radius()){
        //make arc into circle
        m_arc.plane.xaxis = end_point - m_arc.Center();
        m_arc.plane.xaxis.Unitize();
        m_arc.plane.yaxis = ON_CrossProduct(m_arc.Normal(), m_arc.plane.xaxis);
        m_arc.plane.yaxis.Unitize();
        m_arc.SetAngleRadians(2.0*ON_PI);
        rc = true;
      }
    }
  }
  return rc;  
}
Esempio n. 6
0
ON_BOOL32 ON_Torus::ClosestPointTo( 
         ON_3dPoint test_point, 
         double* major__angle_radians, 
         double* minor__angle_radians
       ) const
{
  double major_angle_radians, minor_angle_radians;
  const ON_Circle major_circle(plane,major_radius);
  ON_BOOL32 rc = major_circle.ClosestPointTo( test_point, &major_angle_radians );
  if ( rc && minor__angle_radians )
  {
    EVAL_SETUP_MAJOR;
    ON_3dVector v = test_point - major_radius*raxis;
    rc = v.Unitize();
    if ( rc )
    {
      double sma = v*plane.zaxis;
      double cma = v*raxis;
      minor_angle_radians = atan2(sma,cma);
      if ( minor_angle_radians < 0.0 )
        minor_angle_radians += 2.0*ON_PI;
    }
    else
      minor_angle_radians = 0.0;
    *minor__angle_radians = minor_angle_radians;
  }
  if ( major__angle_radians )
    *major__angle_radians = major_angle_radians;
  return rc;
}
bool ON_PolyEdgeCurve::EvSrfTangent( 
        double t,
        bool bIsoDir,
        ON_3dPoint& srfpoint,
        ON_3dVector& srftangent,
        ON_3dVector& srfnormal
        ) const
{
  ON_3dPoint srfpt;
  ON_3dVector du, dv, duu, duv, dvv;
  bool rc = EvSrfDerivatives(t,srfpoint,du,dv,duu,duv,dvv);
  if (rc )
    rc = ON_EvNormal( 0, du, dv, duu, duv, dvv, srfnormal ) ? true : false;
  if (rc)
  {
    int segment_index = SegmentIndex(t);
    ON_PolyEdgeSegment* seg = SegmentCurve(segment_index);
    if ( seg )
    {
      if ( bIsoDir && seg->IsoType() == ON_Surface::not_iso )
        bIsoDir = false;
      
      ON_3dVector crvtangent = TangentAt(t);
      ON_3dVector binormal = ON_CrossProduct(crvtangent,srfnormal);
      binormal.Unitize();
      if ( seg->ReversedTrimDir() )
        binormal.Reverse();
      // at this point, binormal points "out" and is tangent
      // to the surface.
      if ( bIsoDir )
      {
        du.Unitize();
        dv.Unitize();
        double B_dot_du = binormal*du;
        double B_dot_dv = binormal*dv;
        if ( fabs(B_dot_dv) > fabs(B_dot_du) )
        {
          if (B_dot_dv < 0.0)
            dv.Reverse();
          srftangent = dv;
        }
        else
        {
          if (B_dot_du < 0.0)
            du.Reverse();
          srftangent = du;
        }
      }
      else
        srftangent = binormal;

      if ( seg && seg->m_face && seg->m_face->m_bRev )
        srfnormal.Reverse();
    }
    else
      rc = false;
  }
  return rc;
}
Esempio n. 8
0
ON_3dVector ON_Ellipse::TangentAt( 
                 double t // parameter
                 ) const
{
  ON_3dVector T = DerivativeAt( 1, t );
  T.Unitize();
  return T;
}
Esempio n. 9
0
// ON_BoundingBox::MaximumDistance has a copy/paste bug in it in V4. Using local
// version of this function with the fix so things continue to work under V4 grasshopper
static double RhCmnMaxDistance_Helper(const ON_BoundingBox& bbox, const ON_3dPoint& P)
{
  ON_3dVector V;
  V.x = ( (P.x < 0.5*(bbox.m_min.x+bbox.m_max.x)) ? bbox.m_max.x : bbox.m_min.x) - P.x;
  V.y = ( (P.y < 0.5*(bbox.m_min.y+bbox.m_max.y)) ? bbox.m_max.y : bbox.m_min.y) - P.y;
  V.z = ( (P.z < 0.5*(bbox.m_min.z+bbox.m_max.z)) ? bbox.m_max.z : bbox.m_min.z) - P.z;
  return V.Length();
}
Esempio n. 10
0
int 
ON_PlaneSurface::GetNurbForm( // returns 0: unable to create NURBS representation
                   //            with desired accuracy.
                   //         1: success - returned NURBS parameterization
                   //            matches the surface's to wthe desired accuracy
                   //         2: success - returned NURBS point locus matches
                   //            the surfaces's to the desired accuracy but, on
                   //            the interior of the surface's domain, the 
                   //            surface's parameterization and the NURBS
                   //            parameterization may not match to the 
                   //            desired accuracy.
        ON_NurbsSurface& nurbs,
        double tolerance
        ) const
{
  ON_BOOL32 rc = IsValid();

  if( !rc )
  {
    if (    m_plane.origin.x != ON_UNSET_VALUE 
         && m_plane.xaxis.x != ON_UNSET_VALUE 
         && m_plane.yaxis.x != ON_UNSET_VALUE
         && m_domain[0].IsIncreasing() && m_domain[1].IsIncreasing()
         && m_extents[0].Length() > 0.0 && m_extents[1].Length() > 0.0
         )
    {
      ON_3dVector N = ON_CrossProduct(m_plane.xaxis,m_plane.yaxis);
      if ( N.Length() <= 1.0e-4 )
      {
        ON_WARNING("ON_PlaneSurface::GetNurbForm - using invalid surface.");
        rc = true;
      }
    }
  }

  if ( rc ) 
  {
    nurbs.m_dim = 3;
    nurbs.m_is_rat = 0;
    nurbs.m_order[0] = nurbs.m_order[1] = 2;
    nurbs.m_cv_count[0] = nurbs.m_cv_count[1] = 2;
    nurbs.m_cv_stride[1] = nurbs.m_dim;
    nurbs.m_cv_stride[0] = nurbs.m_cv_stride[1]*nurbs.m_cv_count[1];
    nurbs.ReserveCVCapacity(12);
    nurbs.ReserveKnotCapacity(0,2);
    nurbs.ReserveKnotCapacity(1,2);
    nurbs.m_knot[0][0] = m_domain[0][0];
    nurbs.m_knot[0][1] = m_domain[0][1];
    nurbs.m_knot[1][0] = m_domain[1][0];
    nurbs.m_knot[1][1] = m_domain[1][1];
    nurbs.SetCV( 0, 0, PointAt( m_domain[0][0], m_domain[1][0] ));
    nurbs.SetCV( 0, 1, PointAt( m_domain[0][0], m_domain[1][1] ));
    nurbs.SetCV( 1, 0, PointAt( m_domain[0][1], m_domain[1][0] ));
    nurbs.SetCV( 1, 1, PointAt( m_domain[0][1], m_domain[1][1] ));
  }

  return rc;
}
Esempio n. 11
0
ON_3dVector ON_Polyline::SegmentDirection( int segment_index ) const
{
    ON_3dVector v;
    if ( segment_index >= 0 && segment_index < m_count-1 ) {
        v = m_a[segment_index+1] - m_a[segment_index];
    }
    else {
        v.Zero();
    }
    return v;
}
Esempio n. 12
0
bool ON_Cone::ClosestPointTo(
          ON_3dPoint point,
          double* radial_parameter,
          double* height_parameter
       ) const
{
  // untested code

  bool rc = false;

  ON_3dVector v = (point-plane.origin);
  double x = v*plane.xaxis;
  double y = v*plane.yaxis;
  double z = v*plane.zaxis;

  if ( radial_parameter )
  {
    double a = ( 0.0 == y && 0.0 == x ) ? 0.0 : atan2(y,x);

    if (a > 2.0*ON_PI )
    {
      a -= 2.0*ON_PI;
    }

    if (a < 0.0 )
    {
      a += 2.0*ON_PI;
    }

    *radial_parameter = a;
  }

  if (height_parameter)
  {
    point.x -= plane.origin.x;
    point.y -= plane.origin.y;
    point.z -= plane.origin.z;
    v.x = x;
    v.y = y;
    v.z = 0.0;
    v.Unitize();
    v.x *= radius;
    v.y *= radius;
    ON_Line line(ON_origin, v.x*plane.xaxis + v.y*plane.yaxis + height*plane.zaxis );
    rc = line.ClosestPointTo(point,&z);
    if (rc)
    {
      *height_parameter = z*height;
    }
  }

  return rc;
}
Esempio n. 13
0
ON_3dPoint ON_Torus::ClosestPointTo( ON_3dPoint test_point ) const
{
  const ON_Circle major_circle(plane,major_radius);
  ON_3dPoint C = major_circle.ClosestPointTo( test_point );
  ON_3dVector v = test_point - C;
  if ( !v.Unitize() )
  {
    v = C - plane.origin;
    v.Unitize();
  }
  return C + minor_radius*v;
}
Esempio n. 14
0
ON_3dPoint ON_Circle::ClosestPointTo( const ON_3dPoint& point ) const
{
  ON_3dPoint P;
  ON_3dVector V = plane.ClosestPointTo( point ) - Center();
  if ( V.Unitize() ) {
    V.Unitize();
    P = Center() + Radius()*V;
  }
  else {
    P = PointAt(0.0);
  }
  return P;
}
Esempio n. 15
0
// Try to make up a 1st derivative if one is zero length
static void CookDerivativesHelper( ON_3dVector& du, ON_3dVector& dv, ON_3dVector& duu, ON_3dVector& duv, ON_3dVector& dvv)
{
  bool du_ok = du.LengthSquared() > ON_SQRT_EPSILON;
  bool dv_ok = dv.LengthSquared() > ON_SQRT_EPSILON;

  if( !du_ok || !dv_ok)
  {
    ON_3dVector normal;
    bool normal_ok = ON_EvNormal( 0, du, dv, duu, duv, dvv, normal ) ? true : false;
    if( normal_ok)
      normal_ok = normal.LengthSquared() > ON_SQRT_EPSILON;
   
    if( normal_ok)
    {
      if(( !du_ok) && ( dv_ok && normal_ok))
      {
        du = ON_CrossProduct( dv, normal);
        du_ok = du.Unitize();
        du *= (0.00390625*dv.Length());
      }
      if( du_ok && ( !dv_ok) && normal_ok)
      {
        dv = ON_CrossProduct( normal, du);
        dv_ok = dv.Unitize();
        dv *= (0.00390625*du.Length());
      }
    }
  }
}  
Esempio n. 16
0
ON_3dVector ON_Cone::NormalAt( double radial_parameter, double height_parameter ) const
{
  double s = sin(radial_parameter);
  double c = cos(radial_parameter);
  if ( radius<0.) {
    c = -c;
    s = -s;
  }
  ON_3dVector ds = c*plane.yaxis - s*plane.xaxis;
  ON_3dVector N = ON_CrossProduct( ((radius<0.0)?-ds:ds),
                                   plane.PointAt(radius*c,radius*s,height) - plane.origin
                                   );
  N.Unitize();
  return N;
}
Esempio n. 17
0
bool ON_Plane::CreateFromFrame(
    const ON_3dPoint&  P, // point on the plane
    const ON_3dVector& X, // non-zero vector in plane
    const ON_3dVector& Y  // another non-zero vector in the plane
    )
{
  origin = P;

  xaxis = X;
  xaxis.Unitize();
  yaxis = Y - ON_DotProduct( Y, xaxis)*xaxis;
  yaxis.Unitize();
  zaxis = ON_CrossProduct( xaxis, yaxis );
  bool b = zaxis.Unitize();
  UpdateEquation();
  if ( b )
  {
    // 11 February 2004 Dale Lear
    //     Add more validation checks.
    b = IsValid();
    if ( b )
    {
      // make sure zaxis is perp to Y
      if ( fabs(Y*zaxis) > ON_SQRT_EPSILON*Y.Length() )
        b = false;
    }
  }
  return b;
}
Esempio n. 18
0
ON_BOOL32 ON_Geometry::Translate( const ON_3dVector& delta )
{
  if ( delta.IsZero() )
    return true;
  ON_Xform tr;
  tr.Translation( delta );
  return Transform( tr );
}
Esempio n. 19
0
RH_C_FUNCTION ON_AngularDimension2* ON_AngularDimension2_New(ON_Arc* arc, double offset)
{
  ON_AngularDimension2* rc = NULL;
  if( arc )
  {
    rc = new ON_AngularDimension2();
    ON_3dVector v = arc->StartPoint()-arc->Center();
    v.Unitize();
    ON_3dPoint apex = arc->Center();
    ON_3dPoint p0 = arc->StartPoint();
    ON_3dPoint p1 = arc->EndPoint();
    ON_3dPoint arc_pt = p0 + ( v * offset );
    ON_3dVector normal = arc->Normal();
    rc->CreateFromPoints(apex, p0, p1, arc_pt, normal);
  }
  return rc;
}
Esempio n. 20
0
bool ON_Localizer::CreatePlaneLocalizer( ON_3dPoint P, ON_3dVector N, double h0, double h1 )
{
  Destroy();
  if ( P.IsValid()
       && N.IsValid()
       && N.Length() > 0.0
       && ON_IsValid(h0)
       && ON_IsValid(h1)
       && h0 != h1 )
  {
    m_V = N;
    m_V.Unitize();
    m_P.Set( -(m_V.x*P.x + m_V.y*P.y + m_V.z*P.z), 0.0, 0.0 );
    m_d.Set(h0,h1);
    m_type = plane_type;
  }
  return (plane_type == m_type);
}
Esempio n. 21
0
static
bool ON_BrepExtrudeHelper_CheckPathCurve( const ON_Curve& path_curve, ON_3dVector& path_vector )
{
  ON_Line path_line;
  path_line.from = path_curve.PointAtStart();
  path_line.to = path_curve.PointAtEnd();
  path_vector = path_line.Direction();
  return ( path_vector.IsZero() ? false : true );
}
Esempio n. 22
0
void arbaxis(const ON_3dVector& givenaxis, ON_3dVector& newaxis)
{
  if(fabs(givenaxis[0]) < ARBBOUND && fabs(givenaxis[1]) < ARBBOUND) // near world z
    newaxis = ON_CrossProduct(ON_yaxis, givenaxis);
  else
    newaxis = ON_CrossProduct(ON_zaxis, givenaxis);

  newaxis.Unitize();
}
Esempio n. 23
0
ON_Surface* ON_PlaneSurface::Offset(
      double offset_distance, 
      double tolerance, 
      double* max_deviation
      ) const
{
  if ( max_deviation )
    *max_deviation = 0.0;
  ON_PlaneSurface* offset_srf = new ON_PlaneSurface(*this);
  ON_3dVector delta = offset_srf->m_plane.zaxis;
  double d = delta.Length();
  if ( fabs(1.0-d) <= ON_SQRT_EPSILON )
    d = 1.0;
  d = offset_distance/d;
  offset_srf->m_plane.origin = offset_srf->m_plane.origin + (d*delta);
  offset_srf->m_plane.UpdateEquation();
  return offset_srf;
}
bool ON_Quaternion::GetRotation(double& angle, ON_3dVector& axis) const
{
  const double s = Length();
  angle = (s > ON_DBL_MIN) ? 2.0*acos(a/s) : 0.0;
  axis.x = b;
  axis.y = c;
  axis.z = d;
  return (axis.Unitize() && s > ON_DBL_MIN);
}
void ON_Quaternion::SetRotation(double angle, const ON_3dVector& axis)
{
  double s = axis.Length();
  s = (s > 0.0) ? sin(0.5*angle)/s : 0.0;
  a = cos(0.5*angle);
  b = s*axis.x;
  c = s*axis.y;
  d = s*axis.z;
}
Esempio n. 26
0
int ON_Intersect( // returns 0 = no intersections, 
                  // 1 = one intersection, 
                  // 2 = 2 intersections
                  // If 0 is returned, first point is point 
                  // on line closest to sphere and 2nd point is the point
                  // on the sphere closest to the line.
                  // If 1 is returned, first point is obtained by evaluating
                  // the line and the second point is obtained by evaluating
                  // the sphere.
                 const ON_Line& line, const ON_Sphere& sphere,
                  ON_3dPoint& A, ON_3dPoint& B // intersection point(s) returned here
                  )
{
  int rc = 0;
  const ON_3dPoint sphere_center = sphere.plane.origin;
  const double sphere_radius = fabs(sphere.radius);
  double tol = sphere_radius*ON_SQRT_EPSILON;
  if ( tol < ON_ZERO_TOLERANCE )
    tol = ON_ZERO_TOLERANCE;
  ON_3dPoint line_center = line.ClosestPointTo(sphere_center);
  double d = line_center.DistanceTo(sphere_center);
  if ( d >= sphere_radius-tol ) {
    rc = ( d <= sphere_radius-tol ) ? 1 : 0;
    A = line_center;
    B = sphere.ClosestPointTo(line_center);
  }
  else {
    d /= sphere_radius;
    double h = sphere_radius*sqrt(1.0 - d*d);
    ON_3dVector V = line.Direction();
    V.Unitize();
    A = sphere.ClosestPointTo(line_center - h*V);
    B = sphere.ClosestPointTo(line_center + h*V);
    d = A.DistanceTo(B);
    if ( d <= ON_ZERO_TOLERANCE ) {
      A = line_center;
      B = sphere.ClosestPointTo(line_center);
      rc = 1;
    }
    else
      rc = 2;
  }
  return rc;
}
Esempio n. 27
0
bool ON_Line::InPlane( ON_Plane& plane, double tolerance ) const
{
  const ON_3dVector v = to-from;
  const bool bTinyX = fabs(v.x) <= tolerance;
  const bool bTinyY = fabs(v.y) <= tolerance;
  const bool bTinyZ = fabs(v.z) <= tolerance;
  bool rc = true;
  ON_3dVector X;
  ON_3dVector Y;
  if ( bTinyZ && ( !bTinyX || !bTinyY ) )
  {
    X = ON_xaxis;
    Y = ON_yaxis;
  }
  else if ( bTinyX && ( !bTinyY || !bTinyZ ) )
  {
    X = ON_yaxis;
    Y = ON_zaxis;
  }
  else if ( bTinyY && ( !bTinyZ || !bTinyX ) )
  {
    X = ON_zaxis;
    Y = ON_xaxis;
  }
  else
  {
    X = v;
    X.Unitize();
    Y.PerpendicularTo(X);
    if ( bTinyX && bTinyY && bTinyZ )
    {
      rc = false;
      if ( X.IsZero() )
      {
        X = ON_xaxis;
        Y = ON_yaxis;
      }
    }
  }
  plane.CreateFromFrame( from, X, Y );
  return rc;
}
Esempio n. 28
0
bool ON_Localizer::CreateCylinderLocalizer( ON_3dPoint P, ON_3dVector V, double r0, double r1 )
{
  Destroy();
  if (    P.IsValid() 
       && V.IsValid() 
       && V.Length() > 0.0 
       && ON_IsValid(r0) 
       && ON_IsValid(r1) 
       && r0 > 0.0
       && r1 > 0.0
       && r0 != r1 )
  {
    m_P = P;
    m_V = V;
    m_V.Unitize();
    m_d.Set(r0,r1);
    m_type = cylinder_type;
  }
  return (cylinder_type == m_type);
}
Esempio n. 29
0
static double Angle3d(const ON_3dVector& axis, ON_3dVector& from, const ON_3dVector& to)
{
  ON_3dVector x = from, a = to;
  x.Unitize();
  a.Unitize();

  ON_3dVector y = ON_CrossProduct(axis, from);
  y.Unitize();

  double cosa = x * a;

  if(cosa > 1.0 - ON_SQRT_EPSILON)
    return 0.0;
  if(cosa < ON_SQRT_EPSILON - 1.0)
    return ON_PI;

  double sina = a * y;

  return atan2(sina, cosa);
}
Esempio n. 30
0
bool ON_Line::ClosestPointTo( const ON_3dPoint& point, double *t ) const
{
  bool rc = false;
  if ( t ) {
    const ON_3dVector D = Direction();
    const double DoD = D.LengthSquared();
    if ( DoD > 0.0 ) {
      if ( point.DistanceTo(from) <= point.DistanceTo(to) ) {
        *t = ((point - from)*D)/DoD;
      }
      else {
        *t = 1.0 + ((point - to)*D)/DoD;
      }
      rc = true;
    }
    else {
      *t = 0.0;
    }
  }
  return rc;
}