void Cone::Compute_Cylinder_Data() { DBL tmpf; Vector3d axis; axis = apex - base; tmpf = axis.length(); if (tmpf < EPSILON) { throw POV_EXCEPTION_STRING("Degenerate cylinder, base point = apex point."); // TODO FIXME - should a possible error } else { axis /= tmpf; Compute_Coordinate_Transform(Trans, base, axis, apex_radius, tmpf); } dist = 0.0; /* Recalculate the bounds */ Compute_BBox(); }
void Sphere::Scale(const Vector3d& Vector, const TRANSFORM *tr) { if ((Vector[X] != Vector[Y]) || (Vector[X] != Vector[Z])) { if (Trans == NULL) { // treat sphere as ellipsoid as it's unevenly scaled Do_Ellipsoid = true; // FIXME - parser needs to select sphere or ellipsoid Trans = Create_Transform(); } } if (Trans == NULL) { Center *= Vector[X]; Radius *= fabs(Vector[X]); Compute_BBox(); } else { Transform(tr); } }
void Parametric::Transform(const TRANSFORM* tr) { if(Trans == NULL) Trans = Create_Transform(); Compose_Transforms(Trans, tr); Compute_BBox(); }
void Fractal::Transform(const TRANSFORM *tr) { if(Trans == NULL) Trans = Create_Transform(); Compose_Transforms(Trans, tr); Compute_BBox(); }
void IsoSurface::Transform(const TRANSFORM* tr) { if(Trans == NULL) Trans = Create_Transform(); Compose_Transforms(Trans, tr); Compute_BBox(); }
void Disc::Transform(const TRANSFORM *tr) { MTransNormal(normal, normal, tr); normal.normalize(); Compose_Transforms(Trans, tr); /* Recalculate the bounds */ Compute_BBox(); }
void Sphere::Transform(const TRANSFORM *tr) { if(Trans == NULL) { Do_Ellipsoid = true; Trans = Create_Transform(); } Compose_Transforms(Trans, tr); Compute_BBox(); }
void Plane::Rotate(const VECTOR, const TRANSFORM *tr) { if(Trans == NULL) { MTransDirection(Normal_Vector, Normal_Vector, tr); Compute_BBox(); } else { Transform(tr); } }
void Plane::Translate(const Vector3d& Vector, const TRANSFORM *tr) { if(Trans == NULL) { Distance -= dot(Normal_Vector, Vector); Compute_BBox(); } else { Transform(tr); } }
void Sphere::Rotate(const Vector3d&, const TRANSFORM *tr) { if(Trans == NULL) { MTransPoint(Center, Center, tr); Compute_BBox(); } else { Transform(tr); } }
void Sphere::Translate(const Vector3d& Vector, const TRANSFORM *tr) { if(Trans == NULL) { Center += Vector; Compute_BBox(); } else { Transform(tr); } }
void Polygon::Transform(const TRANSFORM *tr) { Vector3d N; if(Trans == NULL) Trans = Create_Transform(); Compose_Transforms(Trans, tr); N = Vector3d(0.0, 0.0, 1.0); MTransNormal(S_Normal, N, Trans); S_Normal.normalize(); Compute_BBox(); }
void BicubicPatch::Scale(const Vector3d& Vector, const TRANSFORM *) { int i, j; for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { Control_Points[i][j] *= Vector; } } Precompute_Patch_Values(); Compute_BBox(); }
void BicubicPatch::Transform(const TRANSFORM *tr) { int i, j; for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { MTransPoint(Control_Points[i][j], Control_Points[i][j], tr); } } Precompute_Patch_Values(); Compute_BBox(); }
void Plane::Translate(const VECTOR Vector, const TRANSFORM *tr) { VECTOR Translation; if(Trans == NULL) { VEvaluate (Translation, Normal_Vector, Vector); Distance -= Translation[X] + Translation[Y] + Translation[Z]; Compute_BBox(); } else { Transform(tr); } }
void Plane::Scale(const Vector3d& Vector, const TRANSFORM *tr) { DBL Length; if(Trans == NULL) { Normal_Vector /= Vector; Length = Normal_Vector.length(); Normal_Vector /= Length; Distance /= Length; Compute_BBox(); } else { Transform(tr); } }
void Plane::Scale(const VECTOR Vector, const TRANSFORM *tr) { DBL Length; if(Trans == NULL) { VDivEq(Normal_Vector, Vector); VLength(Length, Normal_Vector); VInverseScaleEq(Normal_Vector, Length); Distance /= Length; Compute_BBox(); } else { Transform(tr); } }
bool Triangle::Compute_Triangle() { int swap; Vector3d V1, V2, Temp; DBL Length; V1 = P1 - P2; V2 = P3 - P2; Normal_Vector = cross(V1, V2); Length = Normal_Vector.length(); /* Set up a flag so we can ignore degenerate triangles */ if (Length == 0.0) { Set_Flag(this, DEGENERATE_FLAG); return(false); } /* Normalize the normal vector. */ Normal_Vector /= Length; Distance = dot(Normal_Vector, P1); Distance *= -1.0; find_triangle_dominant_axis(); swap = false; switch (Dominant_Axis) { case X: if ((P2[Y] - P3[Y])*(P2[Z] - P1[Z]) < (P2[Z] - P3[Z])*(P2[Y] - P1[Y])) { swap = true; } break; case Y: if ((P2[X] - P3[X])*(P2[Z] - P1[Z]) < (P2[Z] - P3[Z])*(P2[X] - P1[X])) { swap = true; } break; case Z: if ((P2[X] - P3[X])*(P2[Y] - P1[Y]) < (P2[Y] - P3[Y])*(P2[X] - P1[X])) { swap = true; } break; } if (swap) { Temp = P2; P2 = P1; P1 = Temp; } /* Build the bounding information from the vertices. */ Compute_BBox(); return(true); }
void Disc::Compute_Disc() { Compute_Coordinate_Transform(Trans, center, normal, 1.0, 1.0); Compute_BBox(); }
void Cone::Compute_Cone_Data() { DBL tlen, len, tmpf; Vector3d tmpv, axis, origin; /* Process the primitive specific information */ /* Find the axis and axis length */ axis = apex - base; len = axis.length(); if (len < EPSILON) { throw POV_EXCEPTION_STRING("Degenerate cone/cylinder."); // TODO FIXME - should a possible error } else { axis /= len; } /* we need to trap that case first */ if (fabs(apex_radius - base_radius) < EPSILON) { /* What we are dealing with here is really a cylinder */ Set_Flag(this, CYLINDER_FLAG); Compute_Cylinder_Data(); return; } if (apex_radius < base_radius) { /* Want the bigger end at the top */ tmpv = base; base = apex; apex = tmpv; tmpf = base_radius; base_radius = apex_radius; apex_radius = tmpf; axis.invert(); } /* apex & base are different, yet, it might looks like a cylinder */ tmpf = base_radius * len / (apex_radius - base_radius); origin = base - axis * tmpf; tlen = tmpf + len; /* apex is always bigger here */ if (((apex_radius - base_radius)*len/tlen) < EPSILON) { /* What we are dealing with here is really a cylinder */ Set_Flag(this, CYLINDER_FLAG); Compute_Cylinder_Data(); return; } dist = tmpf / tlen; /* Determine alignment */ Compute_Coordinate_Transform(Trans, origin, axis, apex_radius, tlen); /* Recalculate the bounds */ Compute_BBox(); }
void Polygon::Compute_Polygon(int number, Vector3d *points) { int i; DBL x, y, z, d; Vector3d o, u, v, w, N; MATRIX a, b; /* Create polygon data. */ if (Data == NULL) { Data = reinterpret_cast<POLYGON_DATA *>(POV_MALLOC(sizeof(POLYGON_DATA), "polygon points")); Data->References = 1; Data->Number = number; Data->Points = reinterpret_cast<Vector2d *>(POV_MALLOC(number*sizeof(Vector2d), "polygon points")); } else { throw POV_EXCEPTION_STRING("Polygon data already computed."); } /* Get polygon's coordinate system (one of the many possible) */ o = points[0]; /* Find valid, i.e. non-zero u vector. */ for (i = 1; i < number; i++) { u = points[i] - o; if (u.lengthSqr() > EPSILON) { break; } } if (i == number) { Set_Flag(this, DEGENERATE_FLAG); ;// TODO MESSAGE Warning("Points in polygon are co-linear. Ignoring polygon."); } /* Find valid, i.e. non-zero v and w vectors. */ for (i++; i < number; i++) { v = points[i] - o; w = cross(u, v); if ((v.lengthSqr() > EPSILON) && (w.lengthSqr() > EPSILON)) { break; } } if (i == number) { Set_Flag(this, DEGENERATE_FLAG); ;// TODO MESSAGE Warning("Points in polygon are co-linear. Ignoring polygon."); } u = cross(v, w); v = cross(w, u); u.normalize(); v.normalize(); w.normalize(); MIdentity(a); MIdentity(b); a[3][0] = -o[X]; a[3][1] = -o[Y]; a[3][2] = -o[Z]; b[0][0] = u[X]; b[1][0] = u[Y]; b[2][0] = u[Z]; b[0][1] = v[X]; b[1][1] = v[Y]; b[2][1] = v[Z]; b[0][2] = w[X]; b[1][2] = w[Y]; b[2][2] = w[Z]; MTimesC(Trans->inverse, a, b); MInvers(Trans->matrix, Trans->inverse); /* Project points onto the u,v-plane (3D --> 2D) */ for (i = 0; i < number; i++) { x = points[i][X] - o[X]; y = points[i][Y] - o[Y]; z = points[i][Z] - o[Z]; d = x * w[X] + y * w[Y] + z * w[Z]; if (fabs(d) > ZERO_TOLERANCE) { Set_Flag(this, DEGENERATE_FLAG); ;// TODO MESSAGE Warning("Points in polygon are not co-planar. Ignoring polygons."); } Data->Points[i][X] = x * u[X] + y * u[Y] + z * u[Z]; Data->Points[i][Y] = x * v[X] + y * v[Y] + z * v[Z]; } N = Vector3d(0.0, 0.0, 1.0); MTransNormal(S_Normal, N, Trans); S_Normal.normalize(); Compute_BBox(); }
void Cone::Transform(const TRANSFORM *tr) { Compose_Transforms(Trans, tr); Compute_BBox(); }
int Fractal::SetUp_Fractal(void) { switch (Algebra) { case QUATERNION_TYPE: switch(Sub_Type) { case CUBE_STYPE: Rules = FractalRulesPtr(new Z3FractalRules()); break; case SQR_STYPE: Rules = FractalRulesPtr(new JuliaFractalRules()); break; default: throw POV_EXCEPTION_STRING("Illegal function: quaternion only supports sqr and cube"); } break; case HYPERCOMPLEX_TYPE: switch (Sub_Type) { case RECIPROCAL_STYPE: Rules = FractalRulesPtr(new HypercomplexReciprocalFractalRules()); break; case EXP_STYPE: case LN_STYPE: case SIN_STYPE: case ASIN_STYPE: case COS_STYPE: case ACOS_STYPE: case TAN_STYPE: case ATAN_STYPE: case SINH_STYPE: case ASINH_STYPE: case COSH_STYPE: case ACOSH_STYPE: case TANH_STYPE: case ATANH_STYPE: case PWR_STYPE: Rules = FractalRulesPtr(new HypercomplexFunctionFractalRules(Complex_Function_List[Sub_Type])); break; case CUBE_STYPE: Rules = FractalRulesPtr(new HypercomplexZ3FractalRules()); break; default: /* SQR_STYPE or else... */ Rules = FractalRulesPtr(new HypercomplexFractalRules()); break; } break; default: throw POV_EXCEPTION_STRING("Algebra unknown in fractal."); } Compute_BBox(); return Num_Iterations; }
void Superellipsoid::Transform(const TRANSFORM *tr) { Compose_Transforms(Trans, tr); Compute_BBox(); }