void PlotDefC::ChangeView(const Coord3D& scaleFactor) { Coord3D viewCenter = GetNewViewCenter(); if (viewCenter.CoordIsNull()) return; Limit3D oldLimits = GetCurrentViewLimits(); Limit3D newLimits; PC_ViewOpRec axesSettings = GetPlotViewOps(); DoOp(axesSettings.xOp, viewCenter.cX, oldLimits.minLim.cX, oldLimits.maxLim.cX, scaleFactor.cX, newLimits.minLim.cX, newLimits.maxLim.cX); DoOp(axesSettings.yOp, viewCenter.cY, oldLimits.minLim.cY, oldLimits.maxLim.cY, scaleFactor.cY, newLimits.minLim.cY, newLimits.maxLim.cY); DoOp(axesSettings.zOp, viewCenter.cZ, oldLimits.minLim.cZ, oldLimits.maxLim.cZ, scaleFactor.cZ, newLimits.minLim.cZ, newLimits.maxLim.cZ); // keep existing 3D az/scale/el PC_View currView = GetCurrentView(); // clear translations currView.translation = Coord3D(0.0); // set new limits currView.viewLimits = newLimits; plotViews.PushStack(currView); ResetView(); }
inline Coord3D repulsionForce(const Coord3D& a, const Coord3D& b, float repulsion, float natlength) { Coord3D diff = a - b; float r = repulsion; r /= cube((std::max)(diff.size() / 2.0f, natlength / 10)); diff = diff * r + Coord3D(frand(-0.01f, 0.01f), frand(-0.01f, 0.01f), frand(-0.01f, 0.01f)); return diff; }
Coord3D SpringLayout::forceLinearSprings(const Coord3D& a, const Coord3D& b, float ideal) { Coord3D diff = (a - b); float dist = diff.size() - ideal; float factor = (std::max)(dist, 0.0f) * m_attraction; // Let springs attract really strong near their equilibrium if (dist > 0.0f) { factor = (std::max)(factor, 100 * m_attraction / (std::max)(dist * dist / 10000.0f, 0.1f)); } return diff * factor; }
void Camera::backward() { Coord3D vect = pos.vectUnitaire(at); pos.setX(pos.getX() - vect.getX()*vitesseDep); pos.setY(pos.getY() - vect.getY()*vitesseDep); pos.setZ(pos.getZ() - vect.getZ()*vitesseDep); at.setX(at.getX() - vect.getX()*vitesseDep); at.setY(at.getY() - vect.getY()*vitesseDep); at.setZ(at.getZ() - vect.getZ()*vitesseDep); }
void OGL3DBase::DrawLine(const Coord3D& stPoint, const Coord3D& endPoint) const { if (stPoint.SameCoord(endPoint)) return; glBegin(GL_LINES); glVertex3d(GLdouble(stPoint.cX), GLdouble(stPoint.cY), GLdouble(stPoint.cZ)); glVertex3d(GLdouble(endPoint.cX), GLdouble(endPoint.cY), GLdouble(endPoint.cZ)); glEnd(); }
void Plate::generate() { this->A = new Coord3D( 0, 0, zWidth); this->B = new Coord3D( size, 0, zWidth); this->C = new Coord3D( size, 0, 0); this->D = new Coord3D( 0, 0, 0); Coord3D * middleABCD = new Coord3D(size / 2, 0 , zWidth / 2); texCoords = new std::vector<Coord2D*>(vertexCount); vertices = new std::vector<Coord3D*>(vertexCount); normals = new std::vector<Coord3D*>(vertexCount); vertices->at(0) = middleABCD; vertices->at(1) = A; vertices->at(2) = B; vertices->at(3) = C; vertices->at(4) = D; vertices->at(5) = A; texCoords->at(0) = new Coord2D(middleABCD->x, middleABCD->z); texCoords->at(1) = new Coord2D(A->x, A->z); texCoords->at(2) = new Coord2D(B->x, B->z); texCoords->at(3) = new Coord2D(C->x, C->z); texCoords->at(4) = new Coord2D(D->x, D->z); texCoords->at(5) = new Coord2D(A->x, A->z); Coord3D * vecAC = *C - A; Coord3D * vecBD = *D - B; Coord3D * normal = vecAC->cross(vecBD); for (int j = 0; j < 6; j++) { normals->at(j) = normal; } delete vecAC, vecBD; }
void Matrix4::UviewDirection(const Coord3D& v21, const Coord3D& up) { double sine, cosine; // find the unit vector that points in the v21 direction Coord3D v_hat_21(v21); double len = v_hat_21.Magnitude(); Matrix4 amat; if (fabs(len) > stdEps) { len = 1.0 / len; v_hat_21 *= len; // rotate z in the xz-plane until same latitude sine = sqrt (1.0 - v_hat_21.cZ * v_hat_21.cZ); amat.RotateY(-v_hat_21.cZ, -sine); } else // error condition: zero length vecotr passed in -- do nothing */ amat.Identity(); // project v21 onto the xy plane Coord3D v_xy(v21); v_xy.cZ = 0.0; len = v_xy.Magnitude(); // rotate in the x-y plane until v21 lies on z axis --- // but of course, if its already there, do nothing Matrix4 bmat, cmat; if (fabs(len) > stdEps) { // want xy projection to be unit vector, so that sines/cosines pop out len = 1.0 / len; v_xy *= len; // rotate the projection of v21 in the xy-plane over to the x axis bmat.RotateZ(v_xy.cX, v_xy.cY); // concatenate these together cmat.MatrixProduct(amat, bmat); } else cmat = amat; /* up vector really should be perpendicular to the x-form direction -- * Use up a couple of cycles, and make sure it is, * just in case the user blew it. */ Coord3D up_proj; up_proj.Perpendicular(up, v_hat_21); len = up_proj.Magnitude(); if (fabs(len) > stdEps) { // normalize the vector len = 1.0/len; up_proj *= len; // compare the up-vector to the y-axis to get the cosine of the angle Coord3D tmp; tmp.cX = cmat.m[1][0]; tmp.cY = cmat.m[1][1]; tmp.cZ = cmat.m[1][2]; cosine = tmp.Dot(up_proj); // compare the up-vector to the x-axis to get the sine of the angle tmp.cX = cmat.m[0][0]; tmp.cY = cmat.m[0][1]; tmp.cZ = cmat.m[0][2]; sine = tmp.Dot(up_proj); // rotate to align the up vector with the y-axis amat.RotateZ(cosine, -sine); // This xform, although computed last, acts first MatrixProduct(amat, cmat); } else { // error condition: up vector is indeterminate (zero length) // -- do nothing *this = cmat; } }
void OGL3DBase::DrawAxesPlane(const SC_DoubleArray& xMajorIncs, const SC_DoubleArray& xMinorIncs, const SC_DoubleArray& yMajorIncs, const SC_DoubleArray& yMinorIncs, const Limit2D& xyLimits, const double& zValue, PC_3DAxesFormat::Axes3DPlanes axPlane, bool xIsLog, bool yIsLog) { Plane3D drawPlane = PC_3DAxesFormat::GetPlane(axPlane); PC_3DAxesFormat& axesFormat = plot3Dbase.axesFormat; Coord3D offComp = GetPixelComponents(axesFormat.axesOffset); offComp.ToModelPlane(drawPlane); Coord3D majTicComp = GetPixelComponents(axesFormat.majorTicLength); majTicComp.ToModelPlane(drawPlane); Coord3D minTicComp = GetPixelComponents(axesFormat.minorTicLength); minTicComp.ToModelPlane(drawPlane); // bottom x Point2D stPoint, majTicEnd, minTicEnd, gridEnd, offsetEnd; stPoint.pY = xyLimits.minLim.pY - offComp.cY; majTicEnd.pY = stPoint.pY + majTicComp.cY; minTicEnd.pY = stPoint.pY + minTicComp.cY; gridEnd.pY = xyLimits.maxLim.pY + offComp.cY; offsetEnd.pY = xyLimits.minLim.pY; PC_AxesFormat wCopy; axesFormat.axesUFormat[axPlane].SetWorkingCopy(wCopy, true); DrawOneAxes(xyLimits.minLim.pX, xyLimits.maxLim.pX, xMajorIncs, xMinorIncs, wCopy, stPoint, majTicEnd, minTicEnd, gridEnd, offsetEnd, stPoint.pX,majTicEnd.pX, minTicEnd.pX, gridEnd.pX, offsetEnd.pX, zValue, drawPlane, xIsLog); // top X stPoint.pY = xyLimits.maxLim.pY + offComp.cY; majTicEnd.pY = stPoint.pY - majTicComp.cY; minTicEnd.pY = stPoint.pY - minTicComp.cY; offsetEnd.pY = xyLimits.maxLim.pY; axesFormat.axesUFormat[axPlane].SetWorkingCopy(wCopy, false); DrawOneAxes(xyLimits.minLim.pX, xyLimits.maxLim.pX, xMajorIncs, xMinorIncs, wCopy, stPoint, majTicEnd, minTicEnd, gridEnd, offsetEnd, stPoint.pX, majTicEnd.pX, minTicEnd.pX, gridEnd.pX, offsetEnd.pX, zValue, drawPlane, xIsLog); // left y stPoint.pX = xyLimits.minLim.pX - offComp.cX; majTicEnd.pX = stPoint.pX + majTicComp.cX; minTicEnd.pX = stPoint.pX + minTicComp.cX; gridEnd.pX = xyLimits.maxLim.pX + offComp.cX; offsetEnd.pX = xyLimits.minLim.pX; axesFormat.axesVFormat[axPlane].SetWorkingCopy(wCopy, true); DrawOneAxes(xyLimits.minLim.pY, xyLimits.maxLim.pY, yMajorIncs, yMinorIncs, wCopy, stPoint, majTicEnd, minTicEnd, gridEnd, offsetEnd, stPoint.pY, majTicEnd.pY, minTicEnd.pY, gridEnd.pY, offsetEnd.pY, zValue, drawPlane, yIsLog); // right Y stPoint.pX = xyLimits.maxLim.pX + offComp.cX; majTicEnd.pX = stPoint.pX - majTicComp.cX; minTicEnd.pX = stPoint.pX - minTicComp.cX; offsetEnd.pX = xyLimits.maxLim.pX; axesFormat.axesVFormat[axPlane].SetWorkingCopy(wCopy, false); DrawOneAxes(xyLimits.minLim.pY, xyLimits.maxLim.pY, yMajorIncs, yMinorIncs, wCopy, stPoint, majTicEnd, minTicEnd, gridEnd, offsetEnd, stPoint.pY, majTicEnd.pY, minTicEnd.pY, gridEnd.pY, offsetEnd.pY ,zValue, drawPlane, yIsLog); }
void OGL3DBase::PerspectiveSetup(double eyeSepMult) { Coord3D zeroOffset(0.0, 0.0, 0.0); Coord3D minCoord = plotBase.GetNormalizedCoord(currView.viewLimits.minLim, zeroOffset); Coord3D maxCoord = plotBase.GetNormalizedCoord(currView.viewLimits.maxLim, zeroOffset);; double maxSceneWidth = minCoord.Distance(maxCoord); double sceneWidth = maxSceneWidth / currView.scale; double fovRadians = Radians(plot3Dbase.fieldOfView); double focalLength = sceneWidth / 2.0 / tan(fovRadians / 2.0); double nearDist = focalLength / 5.0; double farDist = focalLength + maxSceneWidth * 4.0; double wd2 = nearDist * tan(fovRadians); double ndfl = nearDist / focalLength; double eyeSep = focalLength * eyeSepMult; int width, height; plotBase.CalcAvailablePixels(width, height); double aspect = double(width)/ double(height); double left = -aspect * wd2 + eyeSep * ndfl; double right = aspect * wd2 + eyeSep * ndfl; double top = wd2; double bottom = - wd2; glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(left, right, bottom, top, nearDist, farDist); Coord3D spanOffset((1.0 - xOrthoSpan)/ 2.0 , (1.0 - yOrthoSpan)/ 2.0 , (1.0 - zOrthoSpan)/ 2.0 ); Coord3D translation = currView.translation + spanOffset; translation *= (maxCoord - minCoord); Coord3D lookAtPoint = (minCoord + maxCoord) / 2.0; lookAtPoint -= translation; double elevAngle = Radians(currView.elevation); double rotAngle = Radians(currView.azimuth); double dz = focalLength * sin(elevAngle); double xylen = focalLength * cos(elevAngle); double dx = - xylen * sin(rotAngle); double dy = - xylen * cos(rotAngle); Coord3D eyeCoord = lookAtPoint; eyeCoord.cX += dx; eyeCoord.cY += dy; eyeCoord.cZ += dz; Coord3D upVec(0.0, 0.0, 1.0); if (fabs(sin(elevAngle)) > 0.95) { upVec = Coord3D(sin(rotAngle), cos(rotAngle), 0.0); upVec.Normalize(); } if (eyeSep > stdEps) { Coord3D rsep = CrossProduct(eyeCoord, upVec); rsep.Normalize(); rsep *= eyeSep; eyeCoord += rsep; } glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(eyeCoord.cX, eyeCoord.cY, eyeCoord.cZ, lookAtPoint.cX, lookAtPoint.cY, lookAtPoint.cZ, upVec.cX, upVec.cY, upVec.cZ); // denormalize // scale for normalizations glScaled(xOrthoSpan / normSpan.cX, yOrthoSpan / normSpan.cY, zOrthoSpan / normSpan.cZ); // translate again for normalizations glTranslated(-normMin.cX, -normMin.cY, -normMin.cZ); }
bool PC_TransparencySpec::TransparencySetup() { int nobj = plotDef.plotObjList.Size(); objectIsTransparent.AllocAndFill(nobj, false); int nanno = plotDef.annoObjList.Size(); annoIsTransparent.AllocAndFill(nanno, false); if (!useTransparency) return false; // get initial counts & objects int tranCount = 0; for (int i = 0; i < nobj; i++) { const PlotObjC& nextObj = plotDef.plotObjList.GetRef(i); if (nextObj.doPlot && nextObj.StatusOK() && nextObj.SupportsTransparency()) { int objCount = nextObj.GetnTransObjects(); if ((objCount > 0) && (transparencyGroups[nextObj.GetTransGroup()].groupIsTransparent)) { objectIsTransparent[i] = true; tranCount += objCount; } } } int annoTranCount = 0; for (int i = 0; i < nanno; i++) { const AnnoObjC& nextObj = plotDef.annoObjList.GetRef(i); if (nextObj.doPlot && nextObj.StatusOK() && nextObj.SupportsTransparency()) { if (transparencyGroups[nextObj.GetTransGroup()].groupIsTransparent) { annoIsTransparent[i] = true; annoTranCount++; } } } annoOnly = (tranCount == 0); if (annoOnly) return (annoTranCount > 0); PC_View currView = plotDef.GetCurrentView(); Coord3D zeroOffset(0.0, 0.0, 0.0); Coord3D minCoord = plotDef.GetNormalizedCoord(currView.viewLimits.minLim, zeroOffset); Coord3D maxCoord = plotDef.GetNormalizedCoord(currView.viewLimits.maxLim, zeroOffset);; Line3D tempLine(minCoord, maxCoord); double maxLength = tempLine.Length() * 2.0; Coord3D lookAtPoint = tempLine.PointOnLine(0.5); double elevAngle = Radians(currView.elevation); double rotAngle = Radians(currView.azimuth); double dz = maxLength * sin(elevAngle); double xylen = maxLength * cos(elevAngle); double dx = - xylen * sin(rotAngle); double dy = - xylen * cos(rotAngle); eyeCoord = lookAtPoint; eyeCoord.cX += dx; eyeCoord.cY += dy; eyeCoord.cZ += dz; tranObjectList.Alloc(tranCount); tranCount = 0; Coord3D objCoord; double minDist, maxDist; for (int i = 0; i < nobj; i++) if (objectIsTransparent[i]) { PlotObjC& nextObj = plotDef.plotObjList.GetRef(i); nextObj.SetupForGetCoord(); int objCount = nextObj.GetnTransObjects(); for (int j = 0; j < objCount; j++) { ObjectTransDesc& nextDesc = tranObjectList[tranCount]; objCoord = nextObj.GetTransObjectCoord(j); if (objCoord.CoordIsNull()) continue; objCoord = plotDef.GetNormalizedCoord(objCoord, nextObj.offsetCoord); if (objCoord.CoordIsNull()) continue; double nextDist = objCoord.Distance(eyeCoord); if (tranCount == 0) { minDist = nextDist; maxDist = nextDist; } else { if (nextDist < minDist) minDist = nextDist; else if (nextDist > maxDist) maxDist = nextDist; } nextDesc.objDist = nextDist; nextDesc.objRef = &nextObj; nextDesc.objIndex = j; nextDesc.objGroup = nextObj.GetTransGroup(); tranCount++; } } if (tranCount == 0) { annoOnly = (annoTranCount > 0); objectIsTransparent.FillToAlloc(false); return annoOnly; } int ndistanceGroups = tranCount / 500; // now place in buckets for sorting if (ndistanceGroups < 2) { ndistanceGroups = 1; // easy just use 1 bucket objectSortArray.AllocAndSetSize(1); objectSortArray[0].Alloc(tranCount); for (int i = 0; i < tranCount; i++) objectSortArray[0] += &(tranObjectList[i]); } else { if (ndistanceGroups > 5000) ndistanceGroups = 5000; if (ndistanceGroups < 100) ndistanceGroups = 100; objectSortArray.AllocAndSetSize(ndistanceGroups); for (int i = 0; i < ndistanceGroups; i++) objectSortArray[i].SetResizable(tranCount / ndistanceGroups * 5); double deltaDist = (maxDist - minDist) / double(ndistanceGroups); for (int i = 0; i < tranCount; i++) { ObjectTransDesc& nextDesc = tranObjectList[i]; int currGroup = int((nextDesc.objDist - minDist) / deltaDist); if (currGroup >= ndistanceGroups) currGroup = ndistanceGroups - 1; if (currGroup < 0) currGroup = 0; objectSortArray[currGroup] += &nextDesc; } } // now sort each for (int k = 0; k < objectSortArray.Size(); k++) { ObjPtrList& currList = objectSortArray[k]; QSort(currList, 0, currList.UpperBound()); } return true; }
void Coord3D::addToCoord(Coord3D p_Coord3D) { m_x += p_Coord3D.getX(); m_y += p_Coord3D.getY(); m_z += p_Coord3D.getZ(); }