void applyRotationalMapping(QPainterPath& linePath, const CLLineEnding* ending, QPointF point, QPointF second) { if (!ending->getIsEnabledRotationalMapping()) return; QPointF directionVector(point.x() - second.x(), point.y() - second.y()); directionVector = normalizePoint(directionVector); if (directionVector.x() == 0 && directionVector.y() == 0) return; QPointF orthogonlVector; if (directionVector.x() == 0) orthogonlVector = QPointF(directionVector.y(), 0); else orthogonlVector = QPointF(-directionVector.y() * directionVector.x(), 1 - directionVector.y() * directionVector.y()); orthogonlVector = normalizePoint(orthogonlVector); QTransform rotateMatrix(directionVector.x(), directionVector.y(), orthogonlVector.x(), orthogonlVector.y(), 0, 0); linePath = rotateMatrix.map(linePath); }
void Game::addAsteroids(int num) { ofPoint randDirection, randSize, randPos; int randSpeed = 0; float randRotation = 0.0, randValue = 0.0; for (int i = 0; i < num; ++i) { randValue = ofRandom(0.0, 1.0); if (randValue > 0.8) { randSize.x = 120; randSize.y = 120; } else if (randValue > 0.5) { randSize.x = 80; randSize.y = 80; } else { randSize.x = 40; randSize.y = 40; } randDirection.x = ofRandom(-1, 1); randDirection.y = ofRandom(-1, 1); normalizePoint(randDirection); randRotation = ofRandom(-0.5, 0.5); randPos.x = ofRandom(0, ofGetWidth()); randPos.y = ofRandom(0, ofGetHeight()); randSpeed = ofRandom(200, 400); Asteroid *asteroid = new Asteroid(); asteroid->initialize(randSize, randSpeed, randPos, randDirection); asteroid->rotationSpeed = randRotation; asteroids.push_back(asteroid); } }
PersCamera Triangle::getPersCamParamsTwo(Mat equi_image, Vec9f vertices1, Vec9f vertices2){ //Get 3d points vector<Point3d> points1 = convVec9fToPoint3d(vertices1); vector<Point3d> points2 = convVec9fToPoint3d(vertices2); //Put the points together vector<Point3d> points; points.insert(points.end(),points1.begin(),points1.end()); points.insert(points.end(),points2.begin(),points2.end()); // get the center of vertices in 3D. Point3d center = nPointsCenter3d(points); center = normalizePoint(center); EquiTrans tran; double pan = 0.0, tilt = 0.0; tran.convSpherePointToAngles(center, &pan, &tilt); ViewDirection vd; vd.pan = pan; vd.tilt = tilt; // Obtained the initial field of view. double h_fov = -1.0, v_fov = -1.0; nPointsFOV(points, vd, center, h_fov, v_fov); // set the intial camera. PersCamera cam; cam.setCamera(equi_image, h_fov, v_fov, vd); return cam; }
/* * Get the perpective camera that includes the triangle in 3D. * * equi_image: original equirectangular image * vertices: 3D coordinates on unit sphere * * coordinate system: x: depth, y:left-right, z:bottom-top */ PersCamera Triangle::getPersCamParams(Mat equi_image, Vec9f vertices){ // store in Point3d; vector<Point3d> points = convVec9fToPoint3d(vertices); // get the center of vertices in 3D. Point3d center = triangleCenter3d(points); center = normalizePoint(center); EquiTrans tran; double pan = 0.0, tilt = 0.0; tran.convSpherePointToAngles(center, &pan, &tilt); ViewDirection vd; vd.pan = pan; vd.tilt = tilt; // Obtained the initial field of view. double h_fov = -1.0, v_fov = -1.0; getFOV(points, vd, center, h_fov, v_fov); // set the intial camera. PersCamera cam; cam.setCamera(equi_image, h_fov, v_fov, vd); // adjust the camera. //PersCamera n_cam = adjustPersCam(equi_image, cam, points); return cam; }
/* * Get the mid point between Point a and Point b in 3D. * Normaalized to be unit vector (on the unit sphere) */ cv::Point3d Triangle::midPoint(cv::Point3d a, cv::Point3d b){ Point3d mid; mid.x = (a.x + b.x)/2.0; mid.y = (a.y + b.y)/2.0; mid.z = (a.z + b.z)/2.0; mid = normalizePoint(mid); return mid; }
void GLWidget::mouseReleaseEvent(QMouseEvent* event) { QPointF point = normalizePoint(QPointF(event->x(), event->y())); _inputState.mousePosition(point); if(event->button() == Qt::MiddleButton) { _inputState.mouseButton(InputState::MouseMiddle, false); } if(event->button() == Qt::LeftButton) { _inputState.mouseButton(InputState::MouseLeft, false); } if(event->button() == Qt::RightButton) { _inputState.mouseButton(InputState::MouseRight, false); } event->accept(); }
State collideObjects(PhysicsObject* a, PhysicsObject* b){ State state; state.deltaAngVel = 0; state.deltaPosition = pointMake(0, 0); state.deltaVel = pointMake(0, 0); CollisionPair pairs[2*PHYSICS_OBJECT_MAXIMUM_POINTS]; if(!coarseCollision(a, b)){ return state; } //if a coarse collision happened, we will search for a refined one in each of A's edges. //in this step we try to find every point where B has hitted A and A has hitted B int Acurrent, Anext, Abefore, Bcurrent, Bnext, pairCount=0; //first case--------------------------------------------------------------------------- /* PA1 PA3 \ / \ / PB2---------PB1 \/ PA2 V=A --=B */ for (Acurrent=0; Acurrent<a->format.polygonInfo.count; Acurrent++) { /*Given 3 sequenced vertex, we create two vectors, one from the first to the second vertex and other from the second to the third vertex.*/ Anext = Acurrent==a->format.polygonInfo.count-1?0:Acurrent+1; Abefore = Acurrent==0?a->format.polygonInfo.count-1:Acurrent-1; Point PA1 = worldPosition(a->format.polygonInfo.points[Abefore],*a); Point PA2 = worldPosition(a->format.polygonInfo.points[Acurrent],*a); Point PA3 = worldPosition(a->format.polygonInfo.points[Anext],*a); Vector A1 = pointMake(PA2.x-PA1.x, PA2.y-PA1.y); Vector A2 = pointMake(PA3.x-PA2.x, PA3.y-PA2.y); pairs[pairCount].depth = 0; pairs[pairCount].normal = pointMake(0, 0); for (Bcurrent = 0; Bcurrent<b->format.polygonInfo.count; Bcurrent++) { /*for each edge of B, we will find if any of the edges are hitted by both edges defined before, if thats the case, then A hitted B on that point If both edges of A hitted more than one edge of B, we will keep the highest depth*/ Bnext = Bcurrent==b->format.polygonInfo.count-1?0:Bcurrent+1; Point PB1 = worldPosition(b->format.polygonInfo.points[Bcurrent], *b); Point PB2 = worldPosition(b->format.polygonInfo.points[Bnext], *b); Vector B = pointMake(PB2.x-PB1.x, PB2.y-PB1.y); Vector I1 = pointMake(PB1.x-PA1.x, PB1.y-PA1.y); Vector I2 = pointMake(PB1.x-PA2.x, PB1.y-PA2.y); float crossBI1 = B.x*I1.y-B.y*I1.x; float crossBI2 = B.x*I2.y-B.y*I2.x; float crossAI1 = A1.x*I1.y-A1.y*I1.x; float crossAI2 = A2.x*I2.y-A2.y*I2.x; float crossBA1 = B.x*A1.y-B.y*A1.x; float crossBA2 = B.x*A2.y-B.y*A2.x; crossBA1=crossBA1==0?0.0001:crossBA1; crossBA2=crossBA2==0?0.0001:crossBA2; float t1 = crossAI1/crossBA1; float w1 = crossBI1/crossBA1; float t2 = crossAI2/crossBA2; float w2 = crossBI2/crossBA2; if(t1>0 && t1<1 && w1>0 && w1<1 && t2>0 && t2<1 && w2>0 && w2<1){ //we do have a collision Vector normal = rotateVector(B, -PI*0.5); //rotate the edge by -90 degrees, so that it points outside normalizePoint(&normal); Point collisionPoint=pointMake(((PA1.x+w1*A1.x)+(PA2.x+w2*A2.x))*0.5, ((PA1.y+w1*A1.y)+(PA2.y+w2*A2.y))*0.5); float depth = (PA2.x-collisionPoint.x)*normal.x+(PA2.y-collisionPoint.y)*normal.y; depth = -depth; if(Fabs(depth)>Fabs(pairs[pairCount].depth)){ pairs[pairCount].depth = depth; pairs[pairCount].normal = normal; pairs[pairCount].location=collisionPoint; } } } if(Fabs(pairs[pairCount].depth)>0){ pairCount++; } } //second case--------------------------------------------------------------------------- /* PA1 PA3 \ / \ / PB2---------PB1 \/ PA2 V=B --=A */ //Although we did not change the names, A variables now refers to B while B variables refer to A for (Acurrent=0; Acurrent<b->format.polygonInfo.count; Acurrent++) { /*Given 3 sequenced vertex, we create two vectors, one from the first to the second vertex and other from the second to the third vertex.*/ Anext = Acurrent==b->format.polygonInfo.count-1?0:Acurrent+1; Abefore = Acurrent==0?b->format.polygonInfo.count-1:Acurrent-1; Point PA1 = worldPosition(b->format.polygonInfo.points[Abefore],*b); Point PA2 = worldPosition(b->format.polygonInfo.points[Acurrent],*b); Point PA3 = worldPosition(b->format.polygonInfo.points[Anext],*b); Vector A1 = pointMake(PA2.x-PA1.x, PA2.y-PA1.y); Vector A2 = pointMake(PA3.x-PA2.x, PA3.y-PA2.y); pairs[pairCount].depth = 0; pairs[pairCount].normal = pointMake(0, 0); for (Bcurrent = 0; Bcurrent<a->format.polygonInfo.count; Bcurrent++) { /*for each edge of A, we will find if any of the edges are hitted by both edges defined before, if thats the case, then A hitted B on that point If both edges of B hitted more than one edge of A, we will keep the highest depth*/ Bnext = Bcurrent==a->format.polygonInfo.count-1?0:Bcurrent+1; Point PB1 = worldPosition(a->format.polygonInfo.points[Bcurrent], *a); Point PB2 = worldPosition(a->format.polygonInfo.points[Bnext], *a); Vector B = pointMake(PB2.x-PB1.x, PB2.y-PB1.y); Vector I1 = pointMake(PB1.x-PA1.x, PB1.y-PA1.y); Vector I2 = pointMake(PB1.x-PA2.x, PB1.y-PA2.y); float crossBI1 = B.x*I1.y-B.y*I1.x; float crossBI2 = B.x*I2.y-B.y*I2.x; float crossAI1 = A1.x*I1.y-A1.y*I1.x; float crossAI2 = A2.x*I2.y-A2.y*I2.x; float crossBA1 = B.x*A1.y-B.y*A1.x; float crossBA2 = B.x*A2.y-B.y*A2.x; crossBA1=crossBA1==0?0.0001:crossBA1; crossBA2=crossBA2==0?0.0001:crossBA2; float t1 = crossAI1/crossBA1; float w1 = crossBI1/crossBA1; float t2 = crossAI2/crossBA2; float w2 = crossBI2/crossBA2; if(t1>0 && t1<1 && w1>0 && w1<1 && t2>0 && t2<1 && w2>0 && w2<1){ //we do have a collision Vector normal = rotateVector(B, -PI*0.5); //rotate the edge by -90 degrees, so that it points outside normalizePoint(&normal); Point collisionPoint=pointMake(((PA1.x+w1*A1.x)+(PA2.x+w2*A2.x))*0.5, ((PA1.y+w1*A1.y)+(PA2.y+w2*A2.y))*0.5); float depth = (PA2.x-collisionPoint.x)*normal.x+(PA2.y-collisionPoint.y)*normal.y; if(Fabs(depth)>Fabs(pairs[pairCount].depth)){ pairs[pairCount].depth = depth; pairs[pairCount].normal = normal; pairs[pairCount].location=collisionPoint; } } } if(Fabs(pairs[pairCount].depth)>0){ pairCount++; } } //third case--------------------------------------------------------------------------- /* PA1 PA3 \ PB2 / \ /\ / X X / \/ \ / PA2 \ PB3 PB1 V=A /\=B */ int Bbefore; for (Acurrent=0; Acurrent<a->format.polygonInfo.count; Acurrent++) { /*Given 3 sequenced vertex, we create two vectors, one from the first to the second vertex and other from the second to the third vertex.*/ Anext = Acurrent==a->format.polygonInfo.count-1?0:Acurrent+1; Abefore = Acurrent==0?a->format.polygonInfo.count-1:Acurrent-1; Point PA1 = worldPosition(a->format.polygonInfo.points[Abefore],*a); Point PA2 = worldPosition(a->format.polygonInfo.points[Acurrent],*a); Point PA3 = worldPosition(a->format.polygonInfo.points[Anext],*a); Vector A12 = pointMake(PA2.x-PA1.x, PA2.y-PA1.y); Vector A23 = pointMake(PA3.x-PA2.x, PA3.y-PA2.y); pairs[pairCount].depth = 0; pairs[pairCount].normal = pointMake(0, 0); for (Bcurrent = 0; Bcurrent<b->format.polygonInfo.count; Bcurrent++) { /*for each pair of edge of B, we will find if any of the edges are hitted as shown above*/ Bnext = Bcurrent==b->format.polygonInfo.count-1?0:Bcurrent+1; Bbefore = Bcurrent==0?b->format.polygonInfo.count-1:Bcurrent-1; Point PB1 = worldPosition(b->format.polygonInfo.points[Bbefore], *b); Point PB2 = worldPosition(b->format.polygonInfo.points[Bcurrent], *b); Point PB3 = worldPosition(b->format.polygonInfo.points[Bnext], *b); Vector B12 = pointMake(PB2.x-PB1.x, PB2.y-PB1.y); Vector B23 = pointMake(PB3.x-PB2.x, PB3.y-PB2.y); Vector IA12B23 = pointMake(PB2.x-PA1.x, PB2.y-PA1.y); Vector IA23B12 = pointMake(PB1.x-PA2.x, PB1.y-PA2.y); float crossB12I = B12.x*IA23B12.y-B12.y*IA23B12.x; float crossB23I = B23.x*IA12B23.y-B23.y*IA12B23.x; float crossA12I = A12.x*IA12B23.y-A12.y*IA12B23.x; float crossA23I = A23.x*IA23B12.y-A23.y*IA23B12.x; float crossB12A23 = B12.x*A23.y-B12.y*A23.x; float crossB23A12 = B23.x*A12.y-B23.y*A12.x; crossB23A12=crossB23A12==0?0.0001:crossB23A12; crossB12A23=crossB12A23==0?0.0001:crossB12A23; float t1 = crossA12I/crossB23A12; float w1 = crossB23I/crossB23A12; float t2 = crossA23I/crossB12A23; float w2 = crossB12I/crossB12A23; if(t1>0 && t1<1 && w1>0 && w1<1 && t2>0 && t2<1 && w2>0 && w2<1){ //we do have a collision Point collision1 = pointMake((PA1.x+w1*A12.x), (PA1.y+w1*A12.y)); Point collision2 = pointMake((PA2.x+w2*A23.x), (PA2.y+w2*A23.y)); Vector c12 = pointMake(collision2.x-collision1.x, collision2.y-collision1.y); Vector normal = rotateVector(c12, -PI*0.5); //rotate the edge by -90 degrees, so that it points outside normalizePoint(&normal); Point collisionPoint=pointMake((collision1.x+collision2.x)*0.5, (collision1.y+collision2.y)*0.5); float depth = (PA2.x-PB2.x)*normal.x+(PA2.y-PB2.y)*normal.y; depth = -depth; pairs[pairCount].depth = depth; pairs[pairCount].normal = normal; pairs[pairCount].location=collisionPoint; pairCount++; } } } int currentCollision; //solves the physics part ot the collision for each collision that has happened for (currentCollision =0; currentCollision<pairCount; currentCollision++) { State st = physicsResolution(a,b,pairs[currentCollision]); state.deltaAngVel += st.deltaAngVel; state.deltaPosition=pointMake(st.deltaPosition.x+state.deltaPosition.x, st.deltaPosition.y+state.deltaPosition.y); state.deltaVel=pointMake(st.deltaVel.x+state.deltaVel.x, st.deltaVel.y+state.deltaVel.y); } state.deltaAngVel += a->angularVelocity; state.deltaVel = pointMake(a->linearVelocity.x+state.deltaVel.x, a->linearVelocity.y+state.deltaVel.y); state.deltaPosition = pointMake(a->position.x+state.deltaPosition.x, a->position.y+state.deltaPosition.y); return state; }
GAIAGEO_DECLARE void gaiaNormalizeLonLat (gaiaGeomCollPtr geom) { /* returns a geometry that is the old geometry with all latitudes shifted into the range -90 to 90, and all longitudes shifted into the range -180 to 180. */ int ib; int iv; double x; double y; double z; double m; gaiaPointPtr point; gaiaPolygonPtr polyg; gaiaLinestringPtr line; gaiaRingPtr ring; if (!geom) return; point = geom->FirstPoint; while (point) { normalizePoint (&(point->X), &(point->Y)); point = point->Next; } line = geom->FirstLinestring; while (line) { /* shifting LINESTRINGs */ for (iv = 0; iv < line->Points; iv++) { if (line->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (line->Coords, iv, &x, &y, &z); } else if (line->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (line->Coords, iv, &x, &y, &m); } else if (line->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (line->Coords, iv, &x, &y, &z, &m); } else { gaiaGetPoint (line->Coords, iv, &x, &y); } normalizePoint (&x, &y); if (line->DimensionModel == GAIA_XY_Z) { gaiaSetPointXYZ (line->Coords, iv, x, y, z); } else if (line->DimensionModel == GAIA_XY_M) { gaiaSetPointXYM (line->Coords, iv, x, y, m); } else if (line->DimensionModel == GAIA_XY_Z_M) { gaiaSetPointXYZM (line->Coords, iv, x, y, z, m); } else { gaiaSetPoint (line->Coords, iv, x, y); } } line = line->Next; } polyg = geom->FirstPolygon; while (polyg) { /* shifting POLYGONs */ ring = polyg->Exterior; for (iv = 0; iv < ring->Points; iv++) { /* shifting the EXTERIOR RING */ if (ring->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (ring->Coords, iv, &x, &y, &z); } else if (ring->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (ring->Coords, iv, &x, &y, &m); } else if (ring->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (ring->Coords, iv, &x, &y, &z, &m); } else { gaiaGetPoint (ring->Coords, iv, &x, &y); } normalizePoint (&x, &y); if (ring->DimensionModel == GAIA_XY_Z) { gaiaSetPointXYZ (ring->Coords, iv, x, y, z); } else if (ring->DimensionModel == GAIA_XY_M) { gaiaSetPointXYM (ring->Coords, iv, x, y, m); } else if (ring->DimensionModel == GAIA_XY_Z_M) { gaiaSetPointXYZM (ring->Coords, iv, x, y, z, m); } else { gaiaSetPoint (ring->Coords, iv, x, y); } } for (ib = 0; ib < polyg->NumInteriors; ib++) { /* shifting the INTERIOR RINGs */ ring = polyg->Interiors + ib; for (iv = 0; iv < ring->Points; iv++) { if (ring->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (ring->Coords, iv, &x, &y, &z); } else if (ring->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (ring->Coords, iv, &x, &y, &m); } else if (ring->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (ring->Coords, iv, &x, &y, &z, &m); } else { gaiaGetPoint (ring->Coords, iv, &x, &y); } normalizePoint (&x, &y); if (ring->DimensionModel == GAIA_XY_Z) { gaiaSetPointXYZ (ring->Coords, iv, x, y, z); } else if (ring->DimensionModel == GAIA_XY_M) { gaiaSetPointXYM (ring->Coords, iv, x, y, m); } else if (ring->DimensionModel == GAIA_XY_Z_M) { gaiaSetPointXYZM (ring->Coords, iv, x, y, z, m); } else { gaiaSetPoint (ring->Coords, iv, x, y); } } } polyg = polyg->Next; } gaiaMbrGeometry (geom); }
void GLWidget::mouseMoveEvent(QMouseEvent* event) { QPointF point = normalizePoint(QPointF(event->x(), event->y())); _inputState.mousePosition(point); event->accept(); }