/// <summary> /// draws a 3d-polygon, which is stored in Array. See also <see cref="xyzArray"/> if the <see cref="OpenGlDevice.PolygonMode"/> = <b>Fill</b> and the array is planar then /// the polygon is drawn as filled polygon else as a lined polygon. /// </summary> /// <param name="Array"><see cref="xyzArray"/>hollds the array information</param> public void drawPolyLine(xyzArray Array) { Object Handle = null; if ((RenderKind == RenderKind.SnapBuffer)) { Handle = Selector.RegisterSnapItem(new PolyLineSnappItem3D(Array)); } if ((PolygonMode == PolygonMode.Fill) && (Array.Count > 2) && (Array.planar)) { Loxy L = new Loxy(); PushMatrix(); MulMatrix(Array.Base.ToMatrix()); xyArray A = Array.ToxyArray(); L.Add(A); drawFilledArray2d(this, L); PopMatrix(); if ((RenderKind == RenderKind.SnapBuffer)) { Selector.UnRegisterSnapItem(Handle); } if (PolygonMode == PolygonMode.Fill) { return; } } Primitives3d.drawArrayLined(this, Array); if ((RenderKind == RenderKind.SnapBuffer)) { Selector.UnRegisterSnapItem(Handle); } }
Loxy getLoxy(double UpDown, ref Base Base) { Loxy Result = new Loxy(); if ((Curvextruders != null) && (Curvextruders.Count > 0) && (Curvextruders[0].Count > 3)) { xyzArray A = new xyzArray(); for (int j = 0; j < Curvextruders[0].Count; j++) { A.Add(Curvextruders[0][j].Value(0, UpDown)); } xyz N = A.normal(); Base = Base.DoComplete(Curvextruders[0][0].Value(0, UpDown), N); for (int i = 0; i < Curvextruders.Count; i++) { xyArray _A = new xyArray(); Result.Add(_A); for (int j = 0; j < Curvextruders[i].Count; j++) { xy P = Base.Relativ(Curvextruders[i][j].Value(0, UpDown)).toXY(); _A.Add(P); } if (_A.Count > 0) { _A.Add(_A[0]); } } } return(Result); }
{/// <summary> /// returns the contur of a list of triangles /// </summary> /// <param name="L">List of triangles</param> /// <returns></returns> public static Loxyz GetContour(List <Triangle> L) { Dictionary <xyz, xyz> D = new Dictionary <xyz, xyz>(); for (int i = 0; i < L.Count; i++) { INeighbors N = L[i] as INeighbors; ITriangle T = L[i]; if ((T.GetB() - T.GetA() & T.GetC() - T.GetA()).length() < 0.0000001) { continue; } if (N.GetNeighbor(0) == -1) { D.Add(T.GetA().Toxyz(), T.GetB().Toxyz()); } if (N.GetNeighbor(1) == -1) { D.Add(T.GetB().Toxyz(), T.GetC().Toxyz()); } if (N.GetNeighbor(2) == -1) { D.Add(T.GetC().Toxyz(), T.GetA().Toxyz()); } } Loxyz Result = new Loxyz(); while (true) { if (D.Count == 0) { break; } xyz First = new xyz(0, 0, 0); foreach (KeyValuePair <xyz, xyz> Pt in D) { First = Pt.Key; break; } xyz Current = First; xyzArray A = new xyzArray(); Result.Add(A); while (true) { if (D.ContainsKey(Current)) { xyz C = D[Current]; A.Add(C); D.Remove(Current); Current = C; } else { break; } } } return(Result); }
/// <summary> /// Restricts the Curve to the startpoint A and the endpoint B. The method works regular only if /// A and B are "close to the curve". /// </summary> /// <param name="_A"></param> /// <param name="_B"></param> public virtual void SetBorder(xyz _A, xyz _B) { double Lam = 0; _FromParam = 0; _toParam = 1; xyzArray A = new xyzArray(Resolution + 1); ToArray(A, 0); A.Distance(_A, 1e10, out Lam); double f = System.Math.Round(Lam / Resolution, 5); A.Distance(_B, 1e10, out Lam); double t = System.Math.Round(Lam / Resolution, 5); if (System.Math.Abs(f - t) < 0.00000000001) { //if (_A.dist(_B) <0.000000001) //{ // t = 1 - f; //} if (Value(0).dist(Value(1)) < 0.00000001) { f = 0.000000000001; } if (this is Nurbs3d) { Nurbs3d BS = this as Nurbs3d; f = BS.Knots[2]; t = BS.Knots[BS.Knots.Length - 3]; } } _FromParam = f; _toParam = t; }
/// <summary> /// Converts a length to a param, which can be used in the method <see cref="Value"/>. /// <seealso cref="ParamToLength"/> /// </summary> /// <param name="le">A length</param> /// <returns>A param for using in <see cref="Value"/></returns> public double LengthToParam(double le) { xyzArray a = new xyzArray(Resolution + 1); this.ToArray(a, 0); return(a.LengthToParam(le) / Resolution); }
/// <summary> /// Calculates the distance to an other xyzArray A, if this distance is smaller than MaxDist. Otherwise <see cref="Utils.big"/> will be returned. /// </summary> /// <param name="A">An other xyzArray</param> /// <param name="MaxDist">Maximal distance</param> /// <param name="param">A value for which the nearest point in the array can evaluated with <see cref="Value"/></param> /// <param name="paramA">A value for which the nearest point in the array A can evaluated with <see cref="Value"/></param> /// <returns></returns> public double Distance(xyzArray A, double MaxDist, out double param, out double paramA) { int i; double result = 1e10; double di; double _param, LineLam; paramA = 0; param = 0; for (i = 1; i < A.Count; i++) { LineType L = new LineType(A[i - 1], A[i] - A[i - 1]); di = Distance(L, MaxDist, out _param, out LineLam); if (!Utils.Less(MaxDist, di) && (!Utils.Less(LineLam, 0)) && (!Utils.Less(1, LineLam)) && (Utils.Less(di, result))) { result = di; param = _param; if (Utils.Equals(LineLam, 1)) { paramA = i; } else { paramA = i - 1 + LineLam; } } } return(result); }
/// <summary> /// Gets the smaller rectangle, which contains the curve. /// </summary> /// <returns>A rectangle</returns> protected virtual Box GetMaxrect() { xyzArray a = new xyzArray(Resolution + 1); this.ToArray(a, 0); return(a.MaxBox()); }
/// <summary> /// creates a <see cref="Face"/> in the <see cref="Model.Shell"/> with the points <b>Pts</b>. /// </summary> /// <param name="Pts"><see cref="xyzArray"/> which gives the points of the plane <see cref="Face"/>.</param> /// <returns>plane Face.</returns> public static Face ShellPlane(xyzArray Pts) { Loxyz L = new Loxyz(); L.Count = 1; L[0] = Pts; return(ShellPlane(L)); }
/// <summary> /// GetSide returns for the constants Up, Down, Front, Back, Left, Right a xyzArray, which holds the /// points responding to its side. /// In order to that you can iterate over the values 0 to 5 to get all sides of a box. /// The Sides are clockwise orientated relative to a "screwvector", which heads for the inside of the box. /// </summary> /// <example> /// <code> /// xyzArray a; /// for ( int i = 0; i < 6; i++) /// { /// a = GetSide(i); /// .. do something with a for example: draw it /// } /// /// </code> /// </example> /// <param name="value">The side you prefer, for example /// <see cref="Down">Down,</see> /// <see cref="Up">Up,</see> /// <see cref="Left">Left,</see> /// <see cref="Right">Right,</see> /// <see cref="Front">Front,</see> /// <see cref="Back">Back</see> /// </param> /// /// <returns></returns> public xyzArray GetSide(int value) { xyzArray result = new xyzArray(5); switch (value) { case Down: result[0] = new xyz(0, 0, 0) + Origin; result[1] = new xyz(Size.x, 0, 0) + Origin; result[2] = new xyz(Size.x, Size.y, 0) + Origin; result[3] = new xyz(0, Size.y, 0) + Origin; result[4] = new xyz(0, 0, 0) + Origin; return(result); case Up: result[0] = new xyz(0, 0, Size.z) + Origin; result[1] = new xyz(0, Size.y, Size.z) + Origin; result[2] = new xyz(Size.x, Size.y, Size.z) + Origin; result[3] = new xyz(Size.x, 0, Size.z) + Origin; result[4] = new xyz(0, 0, Size.z) + Origin; return(result); case Front: result[0] = new xyz(0, 0, 0) + Origin; result[1] = new xyz(0, 0, Size.z) + Origin; result[2] = new xyz(Size.x, 0, Size.z) + Origin; result[3] = new xyz(Size.x, 0, 0) + Origin; result[4] = new xyz(0, 0, 0) + Origin; return(result); case Back: result[0] = new xyz(0, Size.y, 0) + Origin; result[1] = new xyz(Size.x, Size.y, 0) + Origin; result[2] = new xyz(Size.x, Size.y, Size.z) + Origin; result[3] = new xyz(0, Size.y, Size.z) + Origin; result[4] = new xyz(0, Size.y, 0) + Origin; return(result); case Right: result[0] = new xyz(Size.x, 0, 0) + Origin; result[1] = new xyz(Size.x, 0, Size.z) + Origin; result[2] = new xyz(Size.x, Size.y, Size.z) + Origin; result[3] = new xyz(Size.x, Size.y, 0) + Origin; result[4] = new xyz(Size.x, 0, 0) + Origin; return(result); case Left: result[0] = new xyz(0, 0, 0) + Origin; result[1] = new xyz(0, Size.y, 0) + Origin; result[2] = new xyz(0, Size.y, Size.z) + Origin; result[3] = new xyz(0, 0, Size.z) + Origin; result[4] = new xyz(0, 0, 0) + Origin; return(result); } return(result); }
/// <summary> /// This method fills values, calculated by the function Value in an array, starting at index. /// </summary> /// <param name="xyzArray">Array for storing the values of the curve</param> /// <param name="index">startindex, from which the values are stored</param> /// <remarks>The array must be initialized until index + resolution + 1</remarks> public virtual void ToArray(xyzArray xyzArray, int index) { for (int i = 0; i <= Resolution; i++) { double t = _FromParam + (_toParam - _FromParam) * i / (float)Resolution; xyzArray[index + i] = Value(t); } }
/// <summary> /// The method transforms every point in the array by the matrix m and returns these points in an array. /// </summary> /// <param name="m">Transformmatrix</param> /// <returns></returns> public xyzArray TransformEx(Matrix m) { xyzArray result = new xyzArray(Count); for (int i = 0; i < Count; i++) { result[i] = this[i].mul(m); } return(result); }
/// <summary> /// Creates a copy of the polygon and retrieves it. /// </summary> /// <returns>A copy of the array</returns> public xyzArray copy() { xyzArray Result = new xyzArray(); Result.planar = planar; Result.Base = Base; this.data.CopyTo(Result.data, 0); return(Result); }
/// <summary> /// Converts a <see cref="xyzArray"/> to an array of float points. /// </summary> /// <param name="src">xyzarray, which will be convrted.</param> /// <returns></returns> public static xyzf[] ToArray(xyzArray src) { xyzf[] Result = new xyzf[src.Count]; for (int i = 0; i < src.Count; i++) { Result[i] = new xyzf((float)src[i].x, (float)src[i].y, (float)src[i].z); } return(Result); }
/// <summary> /// Maultiplicates the points of the array a by a Matrix m. /// </summary> /// <param name="m">The Matrix</param> /// <param name="a">The array containing points, which will be transformed by the matrix m</param> /// <returns></returns> public static xyzArray operator *(Matrix m, xyzArray a) { xyzArray Result = new xyzArray(a.Count); for (int i = 0; i < a.Count; i++) { Result[i] = m * a[i]; } Result.Base = m * a.Base; return(Result); }
/// <summary> /// Calculates the length of a part of the curve, which is given from 0 to the value param. /// <seealso cref="LengthToParam"/> /// </summary> /// <param name="Param">Param until which the length is calculated</param> /// <returns>Returns the length of the curve</returns> public double ParamToLength(double Param) { if (Param >= 1) { Param = 1; } xyzArray a = new xyzArray(Resolution + 1); this.ToArray(a, 0); return(a.ParamToLength((Param) * Resolution)); }
/// <summary> /// Gets true if the Line the box crosses. /// </summary> /// <param name="L">A Line</param> /// <returns>Gets true if the Line the box crosses.</returns> public bool InterSect(LineType L) { for (int i = 0; i < 6; i++) { xyzArray A = GetSide(i); if (IntersectParalellogram(L, A[0], A[1], A[2], A[3])) { return(true); } } return(false); }
/// <summary> /// Gets an array of Resolution+1 interpolationpoints. /// <seealso cref="Resolution"/> <seealso cref="ToArray"/> /// </summary> /// <returns>The interpolytion points</returns> public virtual xyzArray ToxyzArray() { xyzArray Result = new xyzArray(Resolution + 1); for (int i = 0; i <= Resolution; i++) { double t = i / (float)Resolution; xyz p = Value(t); double aaa = Math.Atan2(p.y, p.x); Result[i] = new xyz(p.x, p.y, p.z); } return(Result); }
/// <summary> /// Returns a enveloping <see cref="Box"/> of a <see cref="xyzArray"/> , relative to a base. /// </summary> /// <param name="RelativeBase">Relative to this Base the enveloping Box will be calculated</param> /// <param name="A">the enveloped xyzArray</param> /// <returns>The enveloping Box</returns> internal Box GetMaxBox(Base RelativeBase, xyzArray A) { if (A.Count == 0) { return(Box.ResetBox()); } Box B = GetMaxBox(RelativeBase, A[0]); for (int i = 1; i < A.Count; i++) { B = B.GetMaxBox(RelativeBase, A[i]); } return(B); }
/// <summary> /// Gets the distance to a line. /// </summary> /// <param name="L">A line</param> /// <param name="MaxDist">maximal distance</param> /// <param name="param">Parameter relative to this curve</param> /// <param name="lam">Prameter relative to L</param> /// <returns>The distance</returns> public double Distance(LineType L, double MaxDist, out double param, out double lam) { double result = Utils.big; xyzArray a = new xyzArray(Resolution + 1); this.ToArray(a, 0); double di = a.Distance(L, MaxDist, out param, out lam); if (!Utils.Less(MaxDist, di)) { param = +param / Resolution; result = di; } return(result); }
/// <summary> /// You can initialize an xyzArray with a string.<br/> /// For example: /// xyzArray A; /// A= fromString( /// "0/0/00; /// 10/0/0; /// 10/0/10; /// 0/10/0"); /// </summary> /// <param name="Source">String which sets the values of the array</param> /// <returns></returns> public static xyzArray FromString(string Source) { string[] s = Source.Split(';'); int ct = 0; for (int i = 0; i < s.Length; i++) { int id = s[i].IndexOf(";"); if (id >= 0) { s[i] = s[i].Remove(id, 1); } id = s[i].IndexOf("{"); if (id >= 0) { s[i] = s[i].Remove(id, 1); } id = s[i].IndexOf("}"); if (id >= 0) { s[i] = s[i].Remove(id, 1); } s[i] = s[i].Trim(); if (s[i] != "") { ct++; } } xyzArray Result = new xyzArray(ct); int j = 0; for (int i = 0; i < ct; i++) { if (s[i] != "") { try { Result[j] = xyz.FromString(s[i]); j++; } catch (Exception) { } } } Result.CheckPlanar(); return(Result); }
/// <summary> /// Closes the Nurbs by changing some Controlpoints and Knots. /// </summary> /// <summary> /// Closes a Nurbs by changing some Controlpoints and some Weights. /// </summary> public void Close() { int Count = ControlPoints.Length + Degree; bool Closed = true; double[] k = Utils.UniformKnots(ControlPoints.Length, Degree); for (int i = 0; i < k.Length; i++) { if (k[i] != Knots[i]) { Closed = false; break; } } for (int i = 0; i < Degree; i++) { if (!ControlPoints[i].Equals(ControlPoints[ControlPoints.Length + i - Degree])) { Closed = false; break; } } if (Closed) { return; } // Move ControlPoints to new xyzArray ActualControlPoints = new xyzArray(Count); for (int i = 0; i < ControlPoints.Length; i++) { ActualControlPoints[i] = ControlPoints[i]; } // Move weigths // Add Points Identic to Point[0], Point[1],.. Point[UDegree-1] for (int i = 0; i < Degree; i++) { ActualControlPoints[ControlPoints.Length + i] = ActualControlPoints[i]; } ControlPoints = ActualControlPoints.ToArray(); Knots = Utils.UniformKnots(ActualControlPoints.Count, Degree); }
/// <summary> /// overrides the <see cref="ProjectPoint(xyz)"/> method of <see cref="Surface"/>. /// </summary> /// <param name="Point">Point, wich will be projected th the surface</param> /// <returns>u amd v parameter. A call <b>Point</b></returns> public override xy ProjectPoint(xyz Point) { xyz p = Base.Relativ(Point); xyz PD = new xyz(0, 0, 0); xyz PU = new xyz(0, 0, 0); double Lam = -1; double Param = -1; DownPlane.Cross(new LineType(p, Direction), out Lam, out PD); UpPlane.Cross(new LineType(p, Direction), out Lam, out PU); xyzArray A = CurveArray; xyz R = StandardBase.Relativ(p); double u = Curve.Arcus(new xy(R.X, R.y)); xy PP11 = Curve.Value(u); if (PP11.dist(new xy(R.X, R.Y)) > 0.5) { } else { } A.Distance(new LineType(p, Direction), 1e10, out Param, out Lam); if (Height < 0) { double v = p.dist(PD) / PU.dist(PD); xyz PP = Value(u, v); return(new xy(u, v)); } else { xy pt = Curve.Value(u); xyz K = StandardBase.BaseX * pt.x + StandardBase.BaseY * pt.y; Plane P = new Plane(Base.BaseO, Base.BaseZ); LineType L = new LineType(K, Direction); xyz pkt = new xyz(0, 0, 0); P.Cross(L, out Lam, out pkt); double v = pkt.dist(p) / Height; xyz PP1 = Value(u, v); return(new xy(u, v)); } }
/// <summary> /// overrides the <see cref="Surface.ProjectPoint(xyz)"/> method. /// </summary> /// <param name="Point">is the point, which will be projected.</param> /// <returns>u and v parameters for <see cref="Surface.Value(double, double)"/>.</returns> public override xy ProjectPoint(xyz Point) { if (StartAngle == -1) { RefreshStartAngle(); } xyz Pt = Base.Relativ(Point); double v = StartAngle - System.Math.Atan2(Pt.y, Pt.x); xyz Q = Matrix.Rotation(new xyz(0, 0, 1), v) * Pt; xyzArray A = Curve.ToxyzArray(); double Lam = -1; A.Distance(Q, 1e10, out Lam); xyz N = Value(Lam / Curve.Resolution, v); return(new xy(Lam / Curve.Resolution, v)); }
void SetCurveArray() { Matrix M = StandardBase.ToMatrix();// xyz K = B.BaseO + B.BaseX * P.x + B.BaseY * P.y; _CurveArray = new xyzArray(); if ((Direction.length() == 0) || (Curve == null)) { return; } xyArray xyA = Curve.ToXYArray(); for (int i = 0; i < xyA.Count; i++) { _CurveArray.Add(xyA[i].toXYZ()); } CurveArray = M * _CurveArray; }
/// <summary> /// crosses two triangles <b>t1</b> and <b>t2</b> /// </summary> /// <param name="t1"></param> /// <param name="t2"></param> /// <param name="Lam"></param> /// <param name="Mue"></param> /// <param name="P"></param> /// <param name="Q"></param> /// <returns></returns> public static bool Cross(TriangleF t1, TriangleF t2, out double Lam, out double Mue, out xyz P, out xyz Q) { xyzArray A = new xyzArray(); xyzArray B = new xyzArray(); A.data = new xyz[] { t1.A.Toxyz(), t1.B.Toxyz(), t1.C.Toxyz(), t1.A.Toxyz() }; B.data = new xyz[] { t2.A.Toxyz(), t2.B.Toxyz(), t2.C.Toxyz(), t2.A.Toxyz() }; Lam = -1; Mue = -1; P = new Drawing3d.xyz(0, 0, 0); Q = new Drawing3d.xyz(0, 0, 0); double d = (A.Distance(B, 1e10, out Lam, out Mue)); if (d < 2) { P = A.Value(Lam); Q = B.Value(Mue); return(true); } return(false); }
/// <summary> /// internal. /// </summary> internal static void MeshdrawLined(OpenGlDevice Device, xyzArray A) { PolygonMode Save = Device.PolygonMode; int ID = MeshVertices.Count; for (int i = 0; i < A.Count; i++) { MeshIndices.Add((IndexType)(i + ID)); } for (int i = 0; i < A.Count; i++) { MeshVertices.Add(((Device.ModelMatrix * A[i]).toXYZF())); } MeshMode = PolygonMode.Line; Device._PolygonMode = Save; // verursacht ein renew falls fill MeshCreator.Renew(); if (Entity.Compiling) { if (Device.RenderKind == RenderKind.SnapBuffer) { MeshCreator.Renew(); } } }
/// <summary> /// gets a box in the <see cref="Model.Shell"/> mode. /// </summary> /// <param name="Origin">origin</param> /// <param name="Size">size.</param> /// <returns>a box in <see cref="Model.Shell"/> mode.</returns> public static Solid CreateShellBox(xyz Origin, xyz Size) { Solid Box = new Solid(); Box.Model = Model.Shell; xyz A = Origin; xyz B = Origin + new xyz(Size.x, 0, 0); xyz C = Origin + new xyz(Size.x, Size.y, 0); xyz D = Origin + new xyz(0, Size.y, 0); xyz E = A + new xyz(0, 0, Size.z); xyz F = B + new xyz(0, 0, Size.z); xyz G = C + new xyz(0, 0, Size.z); xyz H = D + new xyz(0, 0, Size.z); xyzArray Points = new xyzArray(4); Points[0] = A; Points[1] = B; Points[2] = C; Points[3] = D; Face _Face = Face.ShellPlane(Points); Box.FaceList.Add(_Face); Points[0] = A; Points[1] = E; Points[2] = F; Points[3] = B; _Face = Face.ShellPlane(Points); Box.FaceList.Add(_Face); Points[0] = B; Points[1] = F; Points[2] = G; Points[3] = C; _Face = Face.ShellPlane(Points); Box.FaceList.Add(_Face); Points[0] = C; Points[1] = G; Points[2] = H; Points[3] = D; _Face = Face.ShellPlane(Points); Box.FaceList.Add(_Face); Points[0] = D; Points[1] = H; Points[2] = E; Points[3] = A; _Face = Face.ShellPlane(Points); Box.FaceList.Add(_Face); Points[0] = H; Points[1] = G; Points[2] = F; Points[3] = E; _Face = Face.ShellPlane(Points); Box.FaceList.Add(_Face); return(Box); }
void RefreshNormals() { Normals = new Loxyz(); Normals.Count = Bounds.Count; DrawPoints = new Loxyz(); DrawPoints.Count = ParamCurves.Count; if (!DrawRelativToSurfaceBase) { for (int i = 0; i < Bounds.Count; i++) { EdgeLoop EL = Bounds[i]; for (int k = 0; k < EL.Count; k++) { Edge E = EL[k]; DrawPoints[i].Add(E.EdgeStart.Value); } } } for (int i = 0; i < ParamCurves.Count; i++) { xyArray A = ParamCurves[i].getxyArrayClosed(false); if (DrawRelativToSurfaceBase) { DrawPoints[i] = A.ToxyzArray(); } int ct = 0; for (int t = 0; t < ParamCurves[i].Count; t++) { ct = ct + ParamCurves[i][t].Resolution; } xyzArray NormalsLoop = new xyzArray(ct); Normals[i] = NormalsLoop; int id = 0; for (int j = 0; j < ParamCurves[i].Count; j++) { List <Face> L = GetFaces(this, i, j); Edge E = Bounds[i][j]; if (L == null) { Normals = null; DrawPoints = null; return; } double SmoothAngle = Parent.SmoothAngle; xyz N = Surface.Normal(0, 0).normalized(); xyz N1 = Surface.Normal(0, 0).normalized(); for (int k = 0; k < L.Count; k++) { if (System.Math.Abs((N1 * L[k].Surface.Normal(0, 0).normalized())) > System.Math.Cos(SmoothAngle)) { N = N + L[k].Surface.Normal(0, 0).normalized(); } } N = N.normalized(); if (DrawRelativToSurfaceBase) { Matrix M = Surface.Base.ToMatrix().invert(); N = M * N - M * new xyz(0, 0, 0); } NormalsLoop[id] = N; id++; } } }