void CameraData::parseXml(QDomNode dataNode) { Vector3D position = Vector3D::fromString(dataNode.namedItem("position").toElement().text()); Vector3D focalPoint = Vector3D::fromString(dataNode.namedItem("focalPoint").toElement().text()); Vector3D viewUp = Vector3D::fromString(dataNode.namedItem("viewUp").toElement().text()); double nearClip = dataNode.namedItem("nearClip").toElement().text().toDouble(); double farClip = dataNode.namedItem("farClip").toElement().text().toDouble(); double parallelScale = dataNode.namedItem("parallelScale").toElement().text().toDouble(); if (similar(viewUp.length(), 0.0)) return; // ignore reading if undefined data double LARGE_NUMBER = 1.0E6; // corresponding to a distance of 1km - unphysical for human-sized data if ((position-focalPoint).length() > LARGE_NUMBER) return; if (focalPoint.length() > LARGE_NUMBER) return; if (fabs(parallelScale) > LARGE_NUMBER) return; this->getCamera(); mCamera->SetClippingRange(nearClip, farClip); mCamera->SetPosition(position.begin()); mCamera->SetFocalPoint(focalPoint.begin()); mCamera->ComputeViewPlaneNormal(); mCamera->SetViewUp(viewUp.begin()); mCamera->SetParallelScale(parallelScale); }
void ConicDomain::evaluate( Mesh::VertexHandle, const Vector3D& point, Vector3D& closest, Vector3D& normal ) const { // translate such that cone point (mPoint) is at origin Vector3D pt = point - mPoint; // find the plane containing both the input point an the axis Vector3D n = mAxis * pt; double len = n.length(); if (len < 1e-12) { // point on axis // choose any plane that does't contain the axis if (fabs(mAxis[0]) <= fabs(mAxis[1]) && fabs(mAxis[0]) < fabs(mAxis[2])) n = mAxis * Vector3D(1,0,0); else if (fabs(mAxis[1]) <= fabs(mAxis[2])) n = mAxis * Vector3D(0,1,0); else n = mAxis * Vector3D(0,0,1); } else { n /= len; } // Find two points that are the intersection of the plane with the // circular cross-section of the cone centered at mPoint Vector3D p1 = mRadius * (n * mAxis); Vector3D p2 = -p1; // Define two lines of intersect between the cone and the plane // as the two lines from the apex to each of p1 and p2. Vector3D apex = mHeight * mAxis; Vector3D v1 = p1 - apex; Vector3D v2 = p2 - apex; // Find closest point on each line to input position double t1 = v1 % (point - apex) / (v1 % v1); double t2 = v2 % (point - apex) / (v2 % v2); // Select the closest of the two p1 = apex + t1*v1; p2 = apex + t2*v2; double t; if ((p1 - point).length_squared() < (p2 - point).length_squared()) { normal = v1 * n; closest = p1; t = t1; } else { normal = v2 * n; closest = p2; t = t2; } // If we're below the apex (t > 0), then the normal // should be in the same direction as the axis. Otherwise // it should be in the opposite direction. if (t * (normal % mAxis) < 0.0) normal = -normal; // normalize and translate normal *= outwardSign / normal.length(); closest += mPoint; }
Geodetic3D SphericalPlanet::toGeodetic3D(const Vector3D& position) const { const Vector3D p = scaleToGeodeticSurface(position); const Vector3D h = position.sub(p); const double height = (h.dot(position) < 0) ? -1 * h.length() : h.length(); return Geodetic3D(toGeodetic2D(p), height); }
void SphericalDomainTest::check_normal( const SphericalDomain& dom, const Vector3D& point, const Vector3D& normal ) { Vector3D vi = point - dom.center(); CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.0, normal.length(), 1e-6 ); vi /= vi.length(); CPPUNIT_ASSERT_VECTORS_EQUAL( vi, normal, 1e-6 ); }
void SphericalDomainTest::check_closest_pt( const SphericalDomain& dom, const Vector3D& input_pt, const Vector3D& output_pt ) { Vector3D vo = output_pt - dom.center(); Vector3D vi = input_pt - dom.center(); CPPUNIT_ASSERT_DOUBLES_EQUAL( dom.radius(), vo.length(), 1e-6 ); vi *= dom.radius() / vi.length(); CPPUNIT_ASSERT_VECTORS_EQUAL( vo, vi, 1e-6 ); }
void Mesh::getIntersection(Ray ray, Intersection &inter, Matrix4x4 trans){ // vector<Face> (face = typedef vector<int> m_faces // vector<Point3D> m_verts double t = -1; double hitTest; Vector3D normal; Point3D point; Intersection boundTest; boundingSphere->getIntersection(ray, boundTest, trans); if(!boundTest.isValid()){ return; } for(std::vector<Face>::const_iterator F = m_faces.begin(); F != m_faces.end(); ++F){ std::vector<int> points = (*F); std::vector<Point3D> vertices = std::vector<Point3D>(); for(int i = 0; i < 3; i++){ vertices.push_back(m_verts.at(points.at(i))); } Vector3D tnorm = (vertices.at(1) - vertices.at(0)). cross(vertices.at(2) - vertices.at(0)); double area = tnorm.length(); tnorm.normalize(); // not sure if necessary hitTest = intersectPlane(ray, vertices.at(0), tnorm); Point3D hit = ray.point + hitTest*ray.vector; bool inTri = true; double areaSum = 0.0; for(int i = 0; i < 3; i++){ Vector3D cross = (vertices.at((i+1)%3) - hit).cross(vertices.at(i%3) - hit); areaSum += cross.length(); } if(std::abs(areaSum - area) > 0.0001) inTri = false; if(inTri && hitTest > 0 && (t < 0 || t > hitTest)){ t = hitTest; point = hit; normal = tnorm; } } if(t < 0) return; //Intersection *ans = (Intersection*)malloc(sizeof(Intersection)); inter = Intersection(point, normal, NULL); }
bool Contorno::colision(Disparo *e) { Vector3D pe = e->getP(); float re = e->getR(); Vector3D vd = pe - p; float l = vd.length(); return l < r + re; }
void CameraDoubleTapHandler::onDown(const G3MEventContext *eventContext, const TouchEvent& touchEvent, CameraContext *cameraContext) { // compute globe point where user tapped const Vector2I pixel = touchEvent.getTouch(0)->getPos(); Camera* camera = cameraContext->getNextCamera(); const Vector3D initialPoint = camera->pixel2PlanetPoint(pixel); if (initialPoint.isNan()) return; // compute central point of view const Vector3D centerPoint = camera->getXYZCenterOfView(); // compute drag parameters const Vector3D axis = initialPoint.cross(centerPoint); const Angle angle = Angle::fromRadians(- IMathUtils::instance()->asin(axis.length()/initialPoint.length()/centerPoint.length())); // compute zoom factor const double height = camera->getGeodeticPosition()._height; const double distance = height * 0.6; // create effect Effect* effect = new DoubleTapEffect(TimeInterval::fromSeconds(0.75), axis, angle, distance); EffectTarget* target = cameraContext->getNextCamera()->getEffectTarget(); eventContext->getEffectsScheduler()->startEffect(effect, target); }
MutableMatrix44D SphericalPlanet::singleDrag(const Vector3D& finalRay) const { // test if initialPoint is valid if (_initialPoint.isNan()) return MutableMatrix44D::invalid(); // compute final point const Vector3D origin = _origin.asVector3D(); MutableVector3D finalPoint = closestIntersection(origin, finalRay).asMutableVector3D(); if (finalPoint.isNan()) { //printf ("--invalid final point in drag!!\n"); finalPoint = closestPointToSphere(origin, finalRay).asMutableVector3D(); } // compute the rotation axis const Vector3D rotationAxis = _initialPoint.cross(finalPoint).asVector3D(); // compute the angle double sinus = rotationAxis.length()/_initialPoint.length()/finalPoint.length(); const Angle rotationDelta = Angle::fromRadians(-IMathUtils::instance()->asin(sinus)); if (rotationDelta.isNan()) return MutableMatrix44D::invalid(); // save params for possible inertial animations _lastDragAxis = rotationAxis.asMutableVector3D(); double radians = rotationDelta._radians; _lastDragRadiansStep = radians - _lastDragRadians; _lastDragRadians = radians; _validSingleDrag = true; // return rotation matrix return MutableMatrix44D::createRotationMatrix(rotationDelta, rotationAxis); }
bool EdgeLengthQualityMetric::evaluate_vertex(PatchData &pd, MsqVertex* vert, double &fval, MsqError &err) { fval=0.0; size_t this_vert = pd.get_vertex_index(vert); size_t other_vert; vector<size_t> adj_verts; Vector3D edg; pd.get_adjacent_vertex_indices(this_vert,adj_verts,err); MSQ_ERRZERO(err); int num_sample_points=adj_verts.size(); double *metric_values=new double[num_sample_points]; MsqVertex* verts = pd.get_vertex_array(err); MSQ_ERRZERO(err); int point_counter=0; while(!adj_verts.empty()){ other_vert=adj_verts.back(); adj_verts.pop_back(); edg[0]=verts[this_vert][0]-verts[other_vert][0]; edg[1]=verts[this_vert][1]-verts[other_vert][1]; edg[2]=verts[this_vert][2]-verts[other_vert][2]; metric_values[point_counter]=edg.length(); ++point_counter; } fval=average_metrics(metric_values,num_sample_points,err); MSQ_ERRZERO(err); delete[] metric_values; return true; }
double Vector3D::distanceToPlane(const Vector3D &plane, const Vector3D &normal) const { double d=-(plane*normal); double num=dabs((*this)*(normal)+d); return num/normal.length(); }
/******************************************************************************* Purpose - *******************************************************************************/ Line3D LinearForm3D::collide(LinearForm3D other) { /* special solution is cross product of normals */ Vector3D spec; spec.cross(createNormalVector(), other.createNormalVector()); if (abs(spec.length()) <= DBL_EPSILON) // planes are parallel return Line3D::invalid(); /* particular solution can be found by solving the equation set of the two * planes, and another perpendicular plane */ Array2D<double> matrixA(3, 3, 0.0f); matrixA[0][0] = A; matrixA[0][1] = B; matrixA[0][2] = C; matrixA[1][0] = other.A; matrixA[1][1] = other.B; matrixA[1][2] = other.C; matrixA[2][0] = spec.x; matrixA[2][1] = spec.y; matrixA[2][2] = spec.z; /* offset of perp plane can be 0, goes through the origin */ Array2D<double> matrixB(3, 1, 0.0f); matrixB[0][0] = -D; matrixB[1][0] = -other.D; matrixB[2][0] = 0; /* Note: in C++ JAMA, we don't have Matrix.solve. Looking at the Java JAMA * source, it seems that because matrixA is square, we use LU decomposition. */ LU<double> lu(matrixA); Array2D<double> res = lu.solve(matrixB); return Line3D(Point3D(res[0][0], res[1][0], res[2][0]), spec); }
int compare_node_coords( Mesh& mesh1, Mesh& mesh2, MsqError& err ) { const double EPSILON = 1e-4; std::vector<Mesh::VertexHandle> verts1, verts2; mesh1.get_all_vertices( verts1, err ); MSQ_ERRZERO(err); mesh2.get_all_vertices( verts2, err ); MSQ_ERRZERO(err); std::vector<MsqVertex> coords1(verts1.size()), coords2(verts2.size()); mesh1.vertices_get_coordinates( arrptr(verts1), arrptr(coords1), verts1.size(), err ); MSQ_ERRZERO(err); mesh2.vertices_get_coordinates( arrptr(verts2), arrptr(coords2), verts2.size(), err ); MSQ_ERRZERO(err); int error_count = 0; assert(verts1.size() == verts2.size()); for (size_t i = 0; i < verts1.size(); ++i) { assert( verts1[i] == verts2[i] ); Vector3D diff = coords1[i] - coords2[i]; if (diff.length() > EPSILON) { std::cerr << "Vertex coordinates differ between calculated and flagged " "meshes for vertex " << (size_t)verts1[i] << std::endl; ++error_count; } } return error_count; }
void CircleDomainTest::test_snap_to() { Vector3D origin(0,0,0); Vector3D z(0,0,1); double rad1 = 4.0/3.0; CircleDomain dom1( origin, z, rad1 ); Vector3D pt( 1, 0, 0 ); dom1.snap_to( 0, pt ); CPPUNIT_ASSERT_VECTORS_EQUAL( Vector3D(rad1,0,0), pt, 1e-6 ); Vector3D a = Vector3D( 1, 2, 3 ); pt = a; dom1.snap_to( 0, pt ); a = Vector3D( 1, 2, 0 ); a *= rad1 / a.length(); CPPUNIT_ASSERT_VECTORS_EQUAL( a, pt, 1e-6 ); Vector3D some_pt(5,-1,6); Vector3D some_dir(-5,-4,1); double rad2 = 1.0; CircleDomain dom2( some_pt, some_dir, rad2 ); a = Vector3D( 0, 0, 0); pt = a; dom2.snap_to( 0, pt ); CPPUNIT_ASSERT_DOUBLES_EQUAL( rad2, (pt - some_pt).length(), 1e-6 ); // rad from center CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, (pt - some_pt) % some_dir, 1e-6 );// in plane CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, ((pt - some_pt) * (a - some_pt)) % some_dir, 1e-6 ); // correct direction from center a = Vector3D( 0, -1, -2 ); pt = a; dom2.snap_to( 0, pt ); CPPUNIT_ASSERT_DOUBLES_EQUAL( rad2, (pt - some_pt).length(), 1e-6 ); // rad from center CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, (pt - some_pt) % some_dir, 1e-6 );// in plane CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, ((pt - some_pt) * (a - some_pt)) % some_dir, 1e-6 ); // correct direction from center }
bool Contorno::colision(Nave *s) { Vector3D pe = s->getP(); float re = s->getR(); Vector3D vd = pe - p; float l = vd.length(); return l < r + re; }
void CameraControl::setStandard3DViewActionSlot() { QAction* action = dynamic_cast<QAction*> (sender()); if (!action) return; Vector3D viewDirection = Vector3D::fromString(action->data().toString()); vtkRendererPtr renderer = this->getRenderer(); if (!renderer) return; vtkCameraPtr camera = this->getCamera(); renderer->ResetCamera(); Vector3D focus(camera->GetFocalPoint()); Vector3D pos = focus - 500 * viewDirection; Vector3D vup(0, 0, 1); //Vector3D dir = (focus-direction).normal(); Vector3D left = cross(vup, viewDirection); if (similar(left.length(), 0.0)) left = Vector3D(1, 0, 0); vup = cross(viewDirection, left).normal(); camera->SetPosition(pos.begin()); camera->SetViewUp(vup.begin()); renderer->ResetCamera(); // let vtk do the zooming base work camera->Dolly(1.5); // zoom in a bit more than the default vtk value renderer->ResetCameraClippingRange(); }
Hit PhongMaterial::apply_material(Vector3D view, Light* light, Hit h) const { h.diffuse = Colour(0.0, 0.0, 0.0); h.specular = Colour(0.0, 0.0, 0.0); Vector3D l = light->position - h.intersection; Vector3D N = h.normal; double r = l.length(); l.normalize(); N.normalize(); view.normalize(); double ldotN = l.dot(N); Vector3D reflected = -l + (2 * ldotN * N); reflected.normalize(); double attenuation = light->falloff[0] + light->falloff[1] * r + light->falloff[2] * r * r; if ((m_kd.R() > 0.0 || m_kd.G() > 0.0 || m_kd.B() > 0.0) && l.dot(N) > 0.0) { attenuation = 1 / attenuation; h.diffuse = (1.0 - m_transparency) * ldotN * attenuation * light->colour * m_kd; } if ((m_ks.R() > 0.0 || m_ks.G() > 0.0 || m_ks.B() > 0.0) && l.dot(N) > 0.0) { Colour phong = phong_coefficient(l, reflected, view, N); h.specular = ldotN * attenuation * light->colour * phong * m_ks; } return h; }
Colour PhongMaterial::getColour(const Vector3D& normal, const Vector3D& viewDirection, const std::list<Light*>& lights, const Colour& ambient, const Point3D& poi, const Primitive* primitive) const { // Get diffuse coefficients Colour kd = getDiffuse(primitive, poi); // First add ambient light. Colour c = kd * ambient; for (std::list<Light*>::const_iterator it = lights.begin(); it != lights.end(); it++) { Light* light = (*it); Vector3D lightDirection = light->position - poi; // Note this needs to point towards the light. lightDirection.normalize(); double dist = lightDirection.length(); Vector3D r = -lightDirection + 2 * (lightDirection.dot(normal)) * normal; Colour contribution = (kd + m_ks * ( pow(r.dot(viewDirection), m_shininess) / normal.dot(lightDirection) )) * light->colour * lightDirection.dot(normal) * (1 / (light->falloff[0] + light->falloff[1] * dist + light->falloff[2] * dist * dist)); // Ignore negative contributions if (contribution.R() >= 0 && contribution.G() >= 0 && contribution.B() >= 0) { c = c + contribution; } } return c; }
Vector3D Vector3D::normalised() const { Vector3D tmp = (*this); tmp /= tmp.length(); return tmp; }
/** * Return the area of the triangle. */ float Triangle::getArea() const { Vector3D e1 = getVtxPosition(1) - getVtxPosition(0); // find edge v0-v1 Vector3D e2 = getVtxPosition(2) - getVtxPosition(0); // find edge v0-v2 Vector3D n = e1 % e2; // n = e1 x e2 float a = 0.5f * std::fabs(n.length()); // area = |n| / 2 return a; }
void CircleDomain::position_from_length( const double from_here[3], double length, double result_point[3], MsqError& ) { Vector3D b = Vector3D(from_here) - mGeom.center(); Vector3D vy = mGeom.normal() * b; Vector3D vx = vy * mGeom.normal(); double angle = length / mGeom.radius(); double x = std::cos( angle ); double y = std::sin( angle ); vy *= y/vy.length(); vx *= x/vx.length(); Vector3D result = vx + vy; result *= mGeom.radius(); result += mGeom.center(); result.get_coordinates( result_point ); }
/** * Computes the radiance returned by tracing the ray r. */ void PhotonMapper::trace(const Ray& ray, int depth, const Color& flux) { Intersection is; Color lIndirect = Color(0.0f, 0.0f, 0.0f); if (mScene->intersect(ray, is)){ if (depth != 0){ Hitpoint hp; hitpointBVH.intersect(is, flux); float type = uniform(); float reflectivity = is.mMaterial->getReflectivity(is); float transparency = is.mMaterial->getTransparency(is); if (type <= reflectivity){ trace(is.getReflectedRay(), depth + 1, flux); return; } else if (type - reflectivity <= transparency){ trace(is.getRefractedRay(), depth + 1, flux); return; } } if (depth < maxDepth || uniform() > p_abs){ float theta = acos(sqrt(1 - uniform())); float phi = 2 * M_PI * uniform(); float x = sin(theta) * cos(phi); float y = sin(theta) * sin(phi); float z = cos(theta); Vector3D nvec(1.0f, 0.0f, 0.0f); Vector3D mvec(0.0f, 1.0f, 0.0f); Vector3D W = is.mNormal; W.normalize(); Vector3D U = nvec % W; if (U.length() < 0.01f) U = mvec % W; Vector3D V = W % U; Vector3D dir = x * U + y * V + z * W; Ray ray2; ray2.orig = is.mPosition; ray2.dir = dir; Color addFlux = M_PI * is.mMaterial->evalBRDF(is, ray.dir) * flux * (is.mNormal * dir); if (depth >= maxDepth) addFlux *= abs_factor; trace(ray2, depth + 1, addFlux); } } }
Vector3D Vector3D::truncVector(Vector3D vector3, float max) { if(vector3.length() > max) { vector3.Normalize(); vector3 *= max; } return vector3; }
///Determ the ray passing through the point (x,y) Ray Camera::getRay(float x, float y) const { Vector3D right = 2.0f/(float)(H_SIZE) * mImageExtentX * mRight; Vector3D up = -2.0f/(float)(V_SIZE) * mImageExtentY * mUp; Vector3D view = mForward - mImageExtentX * mRight + mImageExtentY * mUp; Vector3D d = view + x*right + y*up; float dLength = d.length(); d /= dLength; return Ray(mOrigin, d, mNearPlane, mFarPlane); }
double CMesh::GetEdgeLen(UINT iEdge) { CVertex* pVertex[2]; pVertex[0]=&(m_pVertex[m_pEdge[iEdge].m_iVertex[0]]); pVertex[1]=&(m_pVertex[m_pEdge[iEdge].m_iVertex[1]]); //get the vector Vector3D v = pVertex[0]->m_vPosition-pVertex[1]->m_vPosition; return v.length(); }
Vector3D DonutMetric::getDirection() { std::vector<Vector3D> coords = mArguments->getRefCoords(); if (coords.size()<2) return Vector3D::UnitZ(); Vector3D diff = (coords[1]-coords[0]); if (similar(diff.length(), 0.0)) return Vector3D(0,1,0); return diff.normal(); }
Vector3D Triangle::calculateNormalDifferential(const Point3D& p, const Vector3D& dp, bool isFrontFacing) const { Vector3D n = (mPlanes[0].dot(p) + mPlaneOffsets.x)*getVtxNormal(0) + (mPlanes[1].dot(p) + mPlaneOffsets.y)*getVtxNormal(1) + (mPlanes[2].dot(p) + mPlaneOffsets.z)*getVtxNormal(2); Vector3D dn = mPlanes[0].dot(dp)*getVtxNormal(0) + mPlanes[1].dot(dp)*getVtxNormal(1) + mPlanes[2].dot(dp)*getVtxNormal(2); float sign = isFrontFacing ? 1.0f : -1.0f; float nl = n.length(); return sign * (n.dot(n) * dn - n.dot(dn) * n) / (nl*nl*nl); }
/** * Returns the BRDF at the intersection is for the light direction L. */ Color Phong::evalBRDF(const Intersection& is, const Vector3D& L) { Color c; Vector3D V = -is.mRay.dir; Vector3D N = is.mNormal; Vector3D LV = L + V; Vector3D H = LV / LV.length(); return mDiffColor / M_PI + mSpecColor * pow(H * N, mShininess); }
void Projection::init( const Vector3D& n1, const Vector3D& up1 ) { MsqError err; const Vector3D n = n1/n1.length(); const Vector3D u = up1/up1.length(); // Rotate for projection const Vector3D z( 0., 0., 1. ); Vector3D r = n * z; double angle = r.interior_angle( n, z, err ); Matrix3D rot1 = rotation( r, angle ); // In-plane rotation for up vector Vector3D pu = u - n * (n % u); Vector3D y( 0., 1., 0. ); angle = z.interior_angle( pu, y, err ); Matrix3D rot2 = rotation( z, angle ); this->myTransform = rot1 * rot2; }
/******************************************************************************* Purpose - *******************************************************************************/ double Vector3D::angle(Vector3D v1) { double vDot = dot(v1) / (length() * v1.length()); if (vDot < -1.0) vDot = -1.0; if (vDot > 1.0) vDot = 1.0; return acos(vDot); }