/****************************************************************************** * CagdCoer.c - Handle point coercesions/conversions. * ******************************************************************************* * Written by Gershon Elber, Aug. 90. * ******************************************************************************/ #include "cagd_loc.h" /****************************************************************************** * Coerce Srf/Crv Point from index Index of Points array of Type PType to E2 * * If however Index < 0 Points is considered single point. * ******************************************************************************/ void CagdCoerceToE2(CagdRType *E2Point, CagdRType *Points[CAGD_MAX_PT_SIZE], int Index, CagdPointType PType) { CagdBType IsRational = CAGD_IS_RATIONAL_PT(PType); int i, MaxCoord = CAGD_NUM_OF_PT_COORD(PType); CagdRType *Point; if (MaxCoord > 2) MaxCoord = 2; if (Index < 0) { /* Points is one single point. */ Point = *Points; for (i = 1; i <= MaxCoord; i++) *E2Point++ = IsRational ? Point[i] / Point[W] : Point[i]; } else /* Points is a full arrays from Srf or Crv. */ for (i = 1; i <= MaxCoord; i++) *E2Point++ = IsRational ? Points[i][Index] / Points[W][Index] : Points[i][Index]; for (i = MaxCoord + 1; i <= 2; i++) *E2Point++ = 0.0; } /****************************************************************************** * Coerce Srf/Crv Point from index Index of Points array of Type PType to E3 * * If however Index < 0 Points is considered single point. * ******************************************************************************/ void CagdCoerceToE3(CagdRType *E3Point, CagdRType *Points[CAGD_MAX_PT_SIZE], int Index, CagdPointType PType) { CagdBType IsRational = CAGD_IS_RATIONAL_PT(PType); int i, MaxCoord = CAGD_NUM_OF_PT_COORD(PType); CagdRType *Point; if (MaxCoord > 3) MaxCoord = 3; if (Index < 0) { /* Points is one single point. */ Point = *Points; for (i = 1; i <= MaxCoord; i++) *E3Point++ = IsRational ? Point[i] / Point[W] : Point[i]; } else /* Points is a full arrays from Srf or Crv. */ for (i = 1; i <= MaxCoord; i++) *E3Point++ = IsRational ? Points[i][Index] / Points[W][Index] : Points[i][Index]; for (i = MaxCoord + 1; i <= 3; i++) *E3Point++ = 0.0; } /****************************************************************************** * Coerce Srf/Crv Point from index Index of Points array of Type PType to P2 * * If however Index < 0 Points is considered single point. * ******************************************************************************/ void CagdCoerceToP2(CagdRType *P2Point, CagdRType *Points[CAGD_MAX_PT_SIZE], int Index, CagdPointType PType) { CagdBType IsRational = CAGD_IS_RATIONAL_PT(PType); int i, MaxCoord = CAGD_NUM_OF_PT_COORD(PType); CagdRType *Point; if (MaxCoord > 2) MaxCoord = 2; if (Index < 0) { /* Points is one single point. */ Point = *Points; *P2Point++ = IsRational ? Point[W] : 1.0; for (i = 1; i <= MaxCoord; i++) *P2Point++ = Point[i]; } else { /* Points is a full arrays from Srf or Crv. */ *P2Point++ = IsRational ? Points[W][Index] : 1.0; for (i = 1; i <= MaxCoord; i++) *P2Point++ = Points[i][Index]; } for (i = MaxCoord + 1; i <= 2; i++) *P2Point++ = 0.0; } /****************************************************************************** * Coerce Srf/Crv Point from index Index of Points array of Type PType to P3 * * If however Index < 0 Points is considered single point. * ******************************************************************************/ void CagdCoerceToP3(CagdRType *P3Point, CagdRType *Points[CAGD_MAX_PT_SIZE], int Index, CagdPointType PType) { CagdBType IsRational = CAGD_IS_RATIONAL_PT(PType); int i, MaxCoord = CAGD_NUM_OF_PT_COORD(PType); CagdRType *Point; if (MaxCoord > 3) MaxCoord = 3; if (Index < 0) { /* Points is one single point. */ Point = *Points; *P3Point++ = IsRational ? Point[W] : 1.0; for (i = 1; i <= MaxCoord; i++) *P3Point++ = Point[i]; } else { /* Points is a full arrays from Srf or Crv. */ *P3Point++ = IsRational ? Points[W][Index] : 1.0; for (i = 1; i <= MaxCoord; i++) *P3Point++ = Points[i][Index]; } for (i = MaxCoord + 1; i <= 3; i++) *P3Point++ = 0.0; } /****************************************************************************** * Coerce Points array of point type OldPType to point type NewPType, in place * ******************************************************************************/ void CagdCoercePointsTo(CagdRType *Points[], int Len, CagdPointType OldPType, CagdPointType NewPType) { int i, j, OldIsRational = CAGD_IS_RATIONAL_PT(OldPType), OldNumOfCoords = CAGD_NUM_OF_PT_COORD(OldPType), NewIsRational = CAGD_IS_RATIONAL_PT(NewPType), NewNumOfCoords = CAGD_NUM_OF_PT_COORD(NewPType); CagdRType *NewPoints[CAGD_MAX_PT_SIZE], Pt[CAGD_MAX_PT_SIZE]; for (i = !NewIsRational; i <= NewNumOfCoords; i++) NewPoints[i] = (CagdRType *) CagdMalloc(sizeof(CagdRType) * Len); for (i = 0; i < Len; i++) { switch (NewPType) { case CAGD_PT_E2_TYPE: CagdCoerceToE2(Pt, Points, i, OldPType); break; case CAGD_PT_E3_TYPE: CagdCoerceToE3(Pt, Points, i, OldPType); break; case CAGD_PT_P2_TYPE: CagdCoerceToP2(Pt, Points, i, OldPType); break; case CAGD_PT_P3_TYPE: CagdCoerceToP3(Pt, Points, i, OldPType); break; default: FATAL_ERROR(CAGD_ERR_UNSUPPORT_PT); break; } if (NewIsRational) for (j = 0; j <= NewNumOfCoords; j++) NewPoints[j][i] = Pt[j]; else for (j = 1; j <= NewNumOfCoords; j++) NewPoints[j][i] = Pt[j - 1]; } /* Replace old rep. with new. */ for (i = !OldIsRational; i <= OldNumOfCoords; i++) CagdFree((VoidPtr) Points[i]); for (i = !NewIsRational; i <= NewNumOfCoords; i++) Points[i] = NewPoints[i]; for (; i <= CAGD_MAX_PT_COORD; i++) Points[i] = NULL; } /****************************************************************************** * Coerce Crv to point type PType. * ******************************************************************************/ CagdCrvStruct *CagdCoerceCrvTo(CagdCrvStruct *Crv, CagdPointType PType) { Crv = CagdCrvCopy(Crv); CagdCoercePointsTo(Crv -> Points, Crv -> Length, Crv -> PType, PType); Crv -> PType = PType; return Crv; } /****************************************************************************** * Coerce Srf to point type PType. * ******************************************************************************/ CagdSrfStruct *CagdCoerceSrfTo(CagdSrfStruct *Srf, CagdPointType PType) { Srf = CagdSrfCopy(Srf); CagdCoercePointsTo(Srf -> Points, Srf -> ULength * Srf -> VLength, Srf -> PType, PType); Srf -> PType = PType; return Srf; } /****************************************************************************** * Returns the point which includes the two provided. * ******************************************************************************/ CagdPointType CagdMergePointType(CagdPointType PType1, CagdPointType PType2) { CagdBType IsRational = CAGD_IS_RATIONAL_PT(PType1) || CAGD_IS_RATIONAL_PT(PType2); int NumCoords = MAX(CAGD_NUM_OF_PT_COORD(PType1), CAGD_NUM_OF_PT_COORD(PType2)); return CAGD_MAKE_PT_TYPE(IsRational, NumCoords); }