public ActorPane() : base() { Origin = new Vector(); XAxis = new Vector(1, 0, 0); Normal = new Vector(0, 0, 1); _scaling = 1; }
/// <summary> /// Default constructor. /// </summary> public Camera(Scene scene) { _scene = scene; // set default positioning _position = new Vector(0.0, 0.0, 9.0); _upVec = new Vector(0.0, 1.0, 0.0); _center = new Vector(); // set default field of view fov = new Angle(); fov["deg"] = 28.0; // set default interaction factors dollyFactor = 0.15; panFactor = 0.05; lastDirection = ViewDirection.Front; Frustum = new FrustumDef(); DefaultAnimationOptions.Duration = 4.0; DefaultAnimationOptions.EaseType = EaseType.Quadratic; UseInertia = true; InertiaAnimationOptions = new AnimationOptions() { Duration = 6.0, EaseType = EaseType.Linear }; InertiaType = InteractionType.None; }
/// <summary> /// Projects point onto the plane. /// </summary> public static Coord Project(this IPlane plane, Vector point) { var diff = point - plane.Origin; // point relative to the plane's origin var x = diff.Dot(plane.XAxis); // x projection var y = diff.Dot(plane.YAxis()); // y projection return new Coord(x, y); }
/// <summary> /// Computes the ellipse geometry. /// </summary> /// <remarks> /// This is based on the psuedocode in http://en.wikipedia.org/wiki/Ellipse. /// </remarks> public override void ComputeGeometry() { base.ComputeGeometry(); if (Anchor2 == null) return; // allocate the points int N = ModelingOptions.Global.CircleDivs; if (solidPoints.Length != N) { solidPoints = new Vector[N]; directions = new Vector[N]; } // get the major and minor axes Vector x = Sketch.Plane.LocalX; Vector y = Sketch.Plane.LocalY; Vector center = Center.ToVector(); double a = x.Dot(Anchor2.ToVector() - center); double b = y.Dot(Anchor2.ToVector() - center); // compute the locations of the points var sinbeta = Tilt.Sin(); var cosbeta = Tilt.Cos(); Angle theta = new Angle(); Angle dTheta = Angle.TwoPi / (N-1); _bounds.Reset(); for (int i = 0; i < N; i ++) { double dx = a * theta.Cos() * cosbeta - b * theta.Sin() * sinbeta; double dy = a * theta.Cos() * sinbeta + b * theta.Sin() * cosbeta; solidPoints[i] = center + x * dx + y * dy; _bounds.Resize(solidPoints[i]); theta += dTheta; } // generate the directions for (int i = 0; i < N; i++) { if (i == 0) directions[i] = (solidPoints[i+1] - solidPoints[N - 1]).Normalize(); else if (i == N - 1) directions[i] = (solidPoints[0] - solidPoints[i - 1]).Normalize(); else directions[i] = (solidPoints[i + 1] - solidPoints[i - 1]).Normalize(); } // generate the wireframe points wireframePoints[0] = center + x * a; wireframePoints[1] = center + y * b; wireframePoints[2] = center - x * a; wireframePoints[3] = center - y * b; }
/// <summary> /// Default constructor. /// </summary> /// <param name="parent"></param> public Axis(AxesBox parent) : base(parent) { _tickLength = 8; _labelPane = new LabelPane() { OriginLocation = AnchorLocation.Center }; _labelPane.Label.Body = "label"; Start = new Vector(); Stop = new Vector(); }
/// <summary> /// Performs matrix multiplication on a vector. /// </summary> /// <param name="m"> The <see cref="Matrix"/>. </param> /// <param name="v"> The <see cref="Vector"/>. </param> /// <returns> The resulting <see cref="Vector"/>. </returns> public static Vector operator*(Matrix m, Vector v) { Vector ret = new Vector(); for (int i=0; i<3; i++) { double row = 0; for (int j=0; j<3; j++) { row += (m[i,j] * v[j]); } ret[i] = row; } return ret; }
/// <summary> /// Initialization constructor. /// </summary> /// <param name="center"> The "center" of the line. </param> /// <param name="direction"> The direction. </param> public RefLine(Point center, Vector direction) : this() { Center = center; Direction = direction; }
/// <summary> /// Performs a hit test with two vectors lying on a 3D line. /// </summary> /// <param name="hitLine"> A <see cref="HitLine"/> defining the hit. </param> /// <param name="hit">The point of the hit, if any.</param> /// <returns> True if the entity was hit. </returns> public virtual bool HitTest(HitLine hitLine, out Vector hit) { hit = null; if (!isSet) return false; // check if the line lies entirely outside the box if (hitLine.Back[0] < minima[0] && hitLine.Front[0] < minima[0]) return false; if (hitLine.Back[0] > maxima[0] && hitLine.Front[0] > maxima[0]) return false; if (hitLine.Back[1] < minima[1] && hitLine.Front[1] < minima[1]) return false; if (hitLine.Back[1] > maxima[1] && hitLine.Front[1] > maxima[1]) return false; if (hitLine.Back[2] < minima[2] && hitLine.Front[2] < minima[2]) return false; if (hitLine.Back[2] > maxima[2] && hitLine.Front[2] > maxima[2]) return false; // check if the line lies entirely inside the box if (hitLine.Front[0] > minima[0] && hitLine.Front[0] < maxima[0] && hitLine.Front[1] > minima[1] && hitLine.Front[1] < maxima[1] && hitLine.Front[2] > minima[2] && hitLine.Front[2] < maxima[2]) { hit = hitLine.Front; return true; } // check if the line intersects any of the individual sides if ((GetIntersection(hitLine.Front[0] - minima[0], hitLine.Back[0] - minima[0], hitLine.Front, hitLine.Back, out hit) && InBox(hit, minima, maxima, 1)) || (GetIntersection(hitLine.Front[1] - minima[1], hitLine.Back[1] - minima[1], hitLine.Front, hitLine.Back, out hit) && InBox(hit, minima, maxima, 2)) || (GetIntersection(hitLine.Front[2] - minima[2], hitLine.Back[2] - minima[2], hitLine.Front, hitLine.Back, out hit) && InBox(hit, minima, maxima, 3)) || (GetIntersection(hitLine.Front[0] - maxima[0], hitLine.Back[0] - maxima[0], hitLine.Front, hitLine.Back, out hit) && InBox(hit, minima, maxima, 1)) || (GetIntersection(hitLine.Front[1] - maxima[1], hitLine.Back[1] - maxima[1], hitLine.Front, hitLine.Back, out hit) && InBox(hit, minima, maxima, 2)) || (GetIntersection(hitLine.Front[2] - maxima[2], hitLine.Back[2] - maxima[2], hitLine.Front, hitLine.Back, out hit) && InBox(hit, minima, maxima, 3))) { return true; } return false; }
/// <summary> /// Performs a dot product on two vectors. /// </summary> /// <param name="rhs"> The second <see cref="Vector"/>. </param> /// <returns> The resulting value. </returns> public double Dot(Vector rhs) { return _val[0]*rhs[0] + _val[1]*rhs[1] + _val[2]*rhs[2]; }
public void Points() { Vector p = new Vector(1.0, 2.0, 3.0); Assert.AreEqual(p[1], 2.0); }
/// <summary> /// Initialization constructor. /// </summary> /// <param name="x"> The i component. </param> /// <param name="y"> The j component. </param> /// <param name="z"> The k component. </param> /// <param name="t"> The scalar component. </param> public Quaternion(double t, double x, double y, double z) { scalar = t; vector = new Vector( x, y, z); }
/// <summary> /// Default constructor. /// </summary> public Sketchable() { solidPoints = new Vector[0]; wireframePoints = new Vector[0]; directions = new Vector[0]; }
/// <summary> /// Translates the bounds by the given difference vector. /// </summary> /// <param name="diff"> A <see cref="Vector"/> to translate by. </param> public void Translate(Vector diff) { minima += diff; maxima += diff; }
/// <summary> /// Expands the bounds in all dimensions by the given factor around the center. /// </summary> /// <param name="factor"> </param> /// <remarks> factors less than one make it contract.</remarks> public void Expand(double factor) { Vector center = Center; minima = center + (minima - center) * factor; maxima = center + (maxima - center) * factor; }
/// <summary> /// Resizes the bounds to fit another bounds. /// </summary> /// <param name="other"> Another <see cref="Bounds"/> that needs to fit in this one. </param> public void Resize(Bounds other) { if (other.Minima != null) { if (isSet) // the bounds have already been set { minima.KeepMinima(other.Minima); maxima.KeepMaxima(other.Maxima); } else // the bounds haven't been set { isSet = true; minima = other.Minima.Copy(); maxima = other.Maxima.Copy(); } } }
/// <summary> /// Resizes the bounds to fit x, y, and z. /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <param name="z"></param> public void Resize(double x, double y, double z) { if (isSet) // the bounds have already been set { minima.KeepMinima(x, y, z); maxima.KeepMaxima(x, y, z); } else // the bounds haven't been set { isSet = true; minima = new Vector(x, y, z); maxima = new Vector(x, y, z); } }
/// <summary> /// Resizes the bounds to fit vector. /// </summary> /// <param name="vector"> A <see cref="Vector"/> that needs to fit in the bounds. </param> public void Resize(Vector vector) { if (isSet) // the bounds have already been set { minima.KeepMinima(vector); maxima.KeepMaxima(vector); } else // the bounds haven't been set { isSet = true; minima = vector.Copy(); maxima = vector.Copy(); } }
/// <summary> /// Keeps the largest value in each dimension. /// </summary> /// <param name="other"> Another <see cref="Vector"/>. </param> public void KeepMaxima(Vector other) { for (int i=0; i<3; i++) _val[i] = Math.Max( _val[i], other[i]); }
/// <summary> /// Rotates the vector about the given axis with the given angle. /// </summary> /// <param name="axis"> Axis of rotation. </param> /// <param name="angle"> Angle of rotation. </param> public Vector Rotate(Vector axis, Angle angle) { // quaternion method Quaternion R = new Quaternion(); R.Scalar = (angle/2.0).Cos(); R.Vector = axis.Normalize() * (angle/2.0).Sin(); Quaternion v = new Quaternion(0.0, this); Quaternion res = R * v * R.T(); return res.Vector; }
/// <summary> /// Computes the line's geometry. /// </summary> public override void ComputeGeometry() { base.ComputeGeometry(); double t=6; start = Center.ToVector() - Direction * t; _bounds.Resize(start); stop = Center.ToVector() + Direction * t; _bounds.Resize(stop); }
/// <summary> /// Computes the raw points needed to draw the sketch. /// </summary> public override void ComputeGeometry() { base.ComputeGeometry(); if (IsClosed) { solidPoints = new Vector[Points.Count+1]; directions = new Vector[Points.Count+1]; } else // open { solidPoints = new Vector[Points.Count]; directions = new Vector[Points.Count]; } for (int i=0; i<Points.Count; i++) { solidPoints[i] = Points[i].ToVector(); // compute the direction if (i < Points.Count - 1) directions[i] = (solidPoints[i] - Points[i + 1].ToVector()).Normalize(); else if (Points.Count > 1) // only compute direction if there's more than one point directions[i] = (solidPoints[i] - solidPoints[i - 1]).Normalize(); else directions[i] = new Vector(); _bounds.Resize(solidPoints[i]); } // if closed, the first point needs to be copied to the end if (IsClosed) { solidPoints[Points.Count] = solidPoints[0]; directions[Points.Count] = directions[0]; } // for lines, the solid and wireframe points are the same wireframePoints = solidPoints; }
/// <summary> /// Gets the most outside edges from the scene of a camera. /// </summary> /// <returns> The low and high end of each edge (6 elements).</returns> public Vector[] GetOutsideEdges(Scene scene) { Vector[] edges = new Vector[6]; Vector camPos = scene.Camera.Position; Vector camCenter = scene.Camera.Center; double zVal = minima[2]; // z value of the x and y axes if (camPos[2] + 0.01 < camCenter[2]) // z position of the camera is negative zVal = maxima[2]; // draw the z axis on top // big, fugly if statement if (camPos[0] >= camCenter[0] && camPos[1] >= camCenter[1]) { edges[0] = new Vector(minima[0], maxima[1], zVal); // x axis edges[1] = new Vector(maxima[0], maxima[1], zVal); edges[2] = new Vector(maxima[0], minima[1], zVal); // y axis edges[3] = new Vector(maxima[0], maxima[1], zVal); edges[4] = new Vector(maxima[0], minima[1], minima[2]); // z axis edges[5] = new Vector(maxima[0], minima[1], maxima[2]); } else if (camPos[0] < camCenter[0] && camPos[1] >= camCenter[1]) { edges[0] = new Vector(minima[0], maxima[1], zVal); // x axis edges[1] = new Vector(maxima[0], maxima[1], zVal); edges[2] = new Vector(minima[0], minima[1], zVal); // y axis edges[3] = new Vector(minima[0], maxima[1], zVal); edges[4] = new Vector(maxima[0], maxima[1], minima[2]); // z axis edges[5] = new Vector(maxima[0], maxima[1], maxima[2]); } else if (camPos[0] < camCenter[0] && camPos[1] < camCenter[1]) { edges[0] = new Vector(minima[0], minima[1], zVal); // x axis edges[1] = new Vector(maxima[0], minima[1], zVal); edges[2] = new Vector(minima[0], minima[1], zVal); // y axis edges[3] = new Vector(minima[0], maxima[1], zVal); edges[4] = new Vector(minima[0], maxima[1], minima[2]); // z axis edges[5] = new Vector(minima[0], maxima[1], maxima[2]); } else if (camPos[0] >= camCenter[0] && camPos[1] < camCenter[1]) { edges[0] = new Vector(minima[0], minima[1], minima[2]); // x axis edges[1] = new Vector(maxima[0], minima[1], minima[2]); edges[2] = new Vector(maxima[0], minima[1], minima[2]); // y axis edges[3] = new Vector(maxima[0], maxima[1], minima[2]); edges[4] = new Vector(minima[0], minima[1], minima[2]); // z axis edges[5] = new Vector(minima[0], minima[1], maxima[2]); } return edges; }
/// <summary> /// Default constructor. /// </summary> public Quaternion() { vector = new Vector(); scalar = 0.0; }
/// <summary> /// Finds the furthest corner from the given point. /// </summary> /// <param name="point"> A <see cref="Vector"/> to compute the distance from. </param> /// <returns> A <see cref="Vector"/> representing the furthest corner. </returns> public Vector FurthestCorner(Vector point) { double dist = 0; Vector furthest = null; foreach (Vector corner in Corners) { double dist_ = (point - corner).Magnitude; if (dist_ > dist) { dist = dist_; furthest = corner; } } return furthest; }
/// <summary> /// Initialization constructor. /// </summary> /// <param name="t">The scalar component. </param> /// <param name="v"> The vector component. </param> public Quaternion(double t, Vector v) { scalar = t; vector = v; }
/// <summary> /// Returns true if the hit is inside a specific axis. /// </summary> /// <param name="Hit"> </param> /// <param name="minima"> </param> /// <param name="maxima"> </param> /// <param name="Axis"> </param> /// <returns> True if there's a hit. </returns> protected bool InBox( Vector Hit, Vector minima, Vector maxima, int Axis) { if ( Axis==1 && Hit[2] > minima[2] && Hit[2] < maxima[2] && Hit[1] > minima[1] && Hit[1] < maxima[1]) return true; if ( Axis==2 && Hit[2] > minima[2] && Hit[2] < maxima[2] && Hit[0] > minima[0] && Hit[0] < maxima[0]) return true; if ( Axis==3 && Hit[0] > minima[0] && Hit[0] < maxima[0] && Hit[1] > minima[1] && Hit[1] < maxima[1]) return true; return false; }
public Rectangle(Sketch sketch) : base(sketch) { solidPoints = new Vector[5]; // needs to come back on itself directions = new Vector[5]; wireframePoints = new Vector[4]; // just the corners }
/// <summary> /// Initialization constructor. /// </summary> /// <param name="minima"> The minima. </param> /// <param name="maxima"> The maxima. </param> public Bounds(Vector minima, Vector maxima) { isSet = true; this.minima = minima; this.maxima = maxima; }
protected bool GetIntersection( double fDst1, double fDst2, Vector P1, Vector P2, out Vector Hit) { Hit = null; if ( (fDst1 * fDst2) >= 0.0f) return false; if ( fDst1 == fDst2) return false; Hit = P1 + (P2-P1) * ( -fDst1/(fDst2-fDst1) ); return true; }
/// <summary> /// Performs a cross product on two vectors. /// </summary> /// <param name="rhs"> The second <see cref="Vector"/>. </param> /// <returns> The resulting <see cref="Vector"/>. </returns> public Vector Cross(Vector rhs) { Vector res = new Vector(); res[0] = _val[1]*rhs[2] - _val[2]*rhs[1]; res[1] = _val[2]*rhs[0] - _val[0]*rhs[2]; res[2] = _val[0]*rhs[1] - _val[1]*rhs[0]; return res; }