public IVector <T> Cross(IVector <T> vector) { if (this.Rows != vector.Rows || this.Columns != vector.Columns) { throw new ArgumentException("Vector cross multiplication failed - vectors had different shapes."); } decimal[,] combinedData = new decimal[3, this.Columns]; for (int i = 0; i < this.Columns; i++) { combinedData[0, i] = 1; combinedData[1, i] = this.Data[i, 0]; combinedData[2, i] = vector[i]; } NMatrix cofactors = new NMatrix(combinedData).Cofactors(); decimal[] components = new decimal[cofactors.Columns]; for (int i = 0; i < cofactors.Columns; i++) { components[i] = cofactors[0, i]; } return(new CartesianVector <T>(components)); }
private void OnCanvasPrePaint(NCanvasPaintEventArgs args) { NCanvas canvas = args.TargetNode as NCanvas; if (canvas == null) { return; } // Create a transform matrix for the graphics path NMatrix matrix = NMatrix.CreateRotationMatrix(m_PathAngle * NAngle.Degree2Rad, NPoint.Zero); matrix.Translate(m_PathPositionX, m_PathPositionY); // Create a graphics path containing a rectangle and transform it NGraphicsPath path = new NGraphicsPath(); path.AddRectangle(0, 0, RectWidth, RectHeight); path.Transform(matrix); // Paint the graphics path NPaintVisitor pv = args.PaintVisitor; pv.SetStroke(m_Stroke); pv.SetFill(m_ImageFill); pv.PaintPath(path); // Paint a border around the canvas pv.ClearFill(); pv.SetStroke(NColor.Black, 1); pv.PaintRectangle(0, 0, canvas.Width, canvas.Height); }
protected void OnExportWithDirect2DMenuItemClick(NEventArgs args) { #if SUPPORT_DIRECT2D && DEBUG string fileName = "d:\\D2D_output.png"; NSize imgSize = new NSize(this.Width, this.Height); try { Nevron.Windows.DirectX.ND2DGraphicsHelper gh = new Nevron.Windows.DirectX.ND2DGraphicsHelper(); INGraphics2D pdfG = gh.CreateGraphics((int)imgSize.Width, (int)imgSize.Height); NRegion clip = NRegion.FromRectangle(new NRectangle(0, 0, imgSize.Width, imgSize.Height)); NMatrix canvasTransform = NMatrix.Identity; NMatrix invertedCT = canvasTransform; invertedCT.Invert(); NPaintVisitor visitor = new NPaintVisitor(pdfG, 96, invertedCT, clip); // assign media // forward traverse the display tree visitor.BeginPainting(); VisitDisplaySubtree(visitor); visitor.EndPainting(); gh.SaveToFileAndDispose(fileName); System.Diagnostics.Process.Start(fileName); } catch (Exception x) { NMessageBox.Show(null, x.Message, "Exception", ENMessageBoxButtons.OK); } #endif }
private static void SigmoidNetworkExample() { var X = new NMatrix(1, 2, new double[] { 1.0, 0.5 }); SigmoidNetwork(ref X); }
/// <summary>Creates a new <see cref="TrainingSet"/> instance.</summary> public TrainingSet(NMatrix input, NMatrix ideal) { Assumption.NotNull(input); Assumption.NotNull(ideal); Assumption.IsTrue(input.RowsCount == ideal.RowsCount); Input = input; Ideal = ideal; }
public void MatrixCreationTest() { Assert.True((new NMatrix(0, 1, null)).Invalid); Assert.True((new NMatrix(1, 0, null)).Invalid); Assert.True((new NMatrix(1, 1, null)).Invalid); Assert.False( (new NMatrix(1, 1, new double[] { 1.0 })).Invalid); var MatA = new NMatrix(2, 3, new double[] { 1, 2, 3, 4, 5, 6 }); Assert.Equal(1, MatA[0]); Assert.Equal(2, MatA[1]); Assert.Equal(3, MatA[2]); Assert.Equal(4, MatA[3]); Assert.Equal(5, MatA[4]); Assert.Equal(6, MatA[5]); Assert.Equal(1, MatA[0, 0]); Assert.Equal(2, MatA[0, 1]); Assert.Equal(3, MatA[0, 2]); Assert.Equal(4, MatA[1, 0]); Assert.Equal(5, MatA[1, 1]); Assert.Equal(6, MatA[1, 2]); var MatB = new NMatrix(2, 3, new double[] { 1, 2, 3, 4, 5, 6 }); Assert.True(MatA.Equals(MatB)); }
void RestingContact() { NMatrix AMatrix = new NMatrix(restingContact.Count, restingContact.Count); NVector fVector = new NVector(restingContact.Count); NVector bVector = new NVector(restingContact.Count); ComputeAMatrix(ref AMatrix); ComputeBVector(ref bVector); //Now I need a QP Solver. Not completely sure which one to use, and how. Uncomment when you do this //QP_Solve(AMatrix,bVector,ref fVector); for (int i = 0; i < restingContact.Count; i++) { double force = fVector.GetPosition(i); Vector3 normalDirection = restingContact[i].CollisionLocation; RigidBodyClass classA = restingContact[i].obj1; RigidBodyClass classB = restingContact[i].obj2; //Applying force in the positive direction classA.AddForce((float)force * normalDirection); Vector3 TorqueDistance = restingContact[i].CollisionLocation - classA.GetPosition(); classA.AddTorque(Vector3.Scale(TorqueDistance, (float)force * normalDirection)); force = -1 * force; //Applying force in the negative direction classB.AddForce((float)force * normalDirection); TorqueDistance = restingContact[i].CollisionLocation - classB.GetPosition(); classB.AddTorque(Vector3.Scale(TorqueDistance, (float)force * normalDirection)); } }
public IVector <T> Multyply(IVector <T> vector) { NMatrix result = new NMatrix(this.GetData()); result.Multiply(vector); return(new CartesianVector <T>(result)); }
public IVector <T> Subtract(IVector <T> vector) { NMatrix result = new NMatrix(this.GetData()); result.Subtract(vector); return(new CartesianVector <T>(result)); }
public IVector <T> Divide(IVector <T> vector) { NMatrix result = new NMatrix(this.GetData()); result.Divide(vector); return(new CartesianVector <T>(result)); }
private void SubTest(NMatrix MatA, NMatrix MatB, NMatrix MatC) { var MatSum1 = MatA.Sub(MatB); Assert.False(MatSum1.Invalid); var MatSum2 = MatA.Sub(MatC); Assert.True(MatSum2.Invalid); }
//Helper Functions for Resting Contact void ComputeAMatrix(ref NMatrix aMatrix) { for (int i = 0; i < restingContact.Count; i++) { for (int j = 0; j < restingContact.Count; j++) { aMatrix.SetPosition(i, j, ComputeAij(i, j)); } } }
public void Test2() { IMatrix <double> mat = new NMatrix(new double[, ] { { 1 }, { 4 }, { 7 }, { 10 } }); System.Console.WriteLine(mat); }
private static void SoftmaxExample() { var matA = new NMatrix(1, 3, new double[] { 0.3, 2.9, 4.0 }); Console.WriteLine($"A: {matA.ToString()}"); var matResult = NMath.Softmax(matA); Console.WriteLine($"Softmax(A): {matResult.ToString()}"); }
private void SoftmaxTest() { var matA = new NMatrix(1, 3, new double[] { 0.3, 2.9, 4.0 }); var arrA = new double[] { 0.3, 2.9, 4.0 }; var matResult1 = NMath.Softmax(matA); Assert.False(matResult1.Invalid); var matResult2 = NMath.Softmax(arrA); Assert.True(Enumerable.SequenceEqual(matResult1.RawArray, matResult2)); }
private static NMatrix SigmoidNetwork(ref NMatrix X) { var W1 = new NMatrix(2, 3, new double[] { 0.1, 0.3, 0.5, 0.2, 0.4, 0.6 }); var B1 = new NMatrix(1, 3, new double[] { 0.1, 0.2, 0.3 }); var A1 = X.Dot(W1).Add(B1); Console.WriteLine($"A1: {A1.ToString()}"); var Z1 = A1.Map( (elem) => { return(NMath.Sigmoid(elem)); }); Console.WriteLine($"Z1: {Z1.ToString()}"); var W2 = new NMatrix(3, 2, new double[] { 0.1, 0.4, 0.2, 0.5, 0.3, 0.6 }); var B2 = new NMatrix(1, 2, new double[] { 0.1, 0.2 }); var A2 = Z1.Dot(W2).Add(B2); Console.WriteLine($"A2: {A2.ToString()}"); var Z2 = A2.Map( (elem) => { return(NMath.Sigmoid(elem)); }); Console.WriteLine($"Z2: {Z2.ToString()}"); var W3 = new NMatrix(2, 2, new double[] { 0.1, 0.3, 0.2, 0.4 }); var B3 = new NMatrix(1, 2, new double[] { 0.1, 0.2 }); var A3 = Z2.Dot(W3).Add(B3); Console.WriteLine($"Y(=A3): {A3.ToString()}"); return(A3); }
private void DotTest(NMatrix MatA, NMatrix MatB, NMatrix MatC) { var MatDot1 = MatA.Dot(MatB); Assert.True(MatDot1.Invalid); /* * 1 2 3 6 5 * 4 5 6 . 4 3 * 2 1 */ var MatDot2 = MatA.Dot(MatC); Assert.False(MatDot2.Invalid); }
private void MapTest(NMatrix matA, NMatrix matB, NMatrix matC) { var MatMap1 = matA.Map((elem) => { return(elem * 0.5); }); Assert.False(MatMap1.Invalid); var MatMap2 = matA.Map(matB, (elemA, elemB) => { return(elemA * elemB); }); Assert.False(MatMap2.Invalid); var MatMap3 = matA.Map(matC, (elemA, elemB) => { return(elemA * elemB); }); Assert.True(MatMap3.Invalid); }
private void MultTest() { var MatA = new NMatrix(2, 3, new double[] { 1, 2, 3, 4, 5, 6 }); var MatMult = MatA.Mult(-0.5); var MatAnswer = new NMatrix(MatA.Row, MatA.Col, new double[] { -0.5, -1, -1.5, -2, -2.5, -3 }); Assert.True(MatAnswer.Equals(MatMult)); }
public void MatrixOperatorTest() { var MatA = new NMatrix(2, 3, new double[] { 1, 2, 3, 4, 5, 6 }); var MatB = new NMatrix(2, 3, new double[] { 6, 5, 4, 3, 2, 1 }); var MatC = new NMatrix(3, 2, new double[] { 6, 5, 4, 3, 2, 1 }); MapTest(MatA, MatB, MatC); AddTest(MatA, MatB, MatC); SubTest(MatA, MatB, MatC); DotTest(MatA, MatB, MatC); MultTest(); DivTest(); }
private void DivTest() { var MatA = new NMatrix(2, 3, new double[] { 1, 2, 3, 4, 5, 6 }); var MatDiv = MatA.Div(-2); var MatAnswer = new NMatrix(MatA.Row, MatA.Col, new double[] { -0.5, -1, -1.5, -2, -2.5, -3 }); Assert.True(MatAnswer.Equals(MatDiv)); }
private void OnCanvasPrePaint(NCanvasPaintEventArgs args) { args.PaintVisitor.PushTransform(NMatrix.CreateTranslationMatrix(10, 10)); // input path interiors if (m_ShowInputPathInteriors.Checked) { args.PaintVisitor.ClearStyles(); args.PaintVisitor.SetFill(NColor.LightBlue); for (int i = 0; i < m_InputPaths.Count; i++) { args.PaintVisitor.PaintPath(m_InputPaths[i]); } } // input path outlines if (m_ShowInputPathOutlines.Checked) { args.PaintVisitor.ClearStyles(); args.PaintVisitor.SetStroke(NColor.Black, 1); for (int i = 0; i < m_InputPaths.Count; i++) { args.PaintVisitor.PaintPath(m_InputPaths[i]); } } // output path interior if (m_ShowOutputPathInterior.Checked) { args.PaintVisitor.ClearStyles(); args.PaintVisitor.SetFill(new NColor(NColor.LightCoral, 128)); args.PaintVisitor.PaintPath(m_OutputPath); } // output path outline if (m_ShowOutputPathOutline.Checked) { args.PaintVisitor.ClearStyles(); args.PaintVisitor.SetStroke(NColor.Black, 2); args.PaintVisitor.PaintPath(m_OutputPath); } args.PaintVisitor.PopTransform(); }
public override NMatrix Calibrate(NPaintVisitor visitor, double imgWidth, double imgHeight, NRectangle targetRect) { // Initialize the image transform NMatrix matrix = NMatrix.Identity; // Scale the image so that it fits 2 times in width and 3 times in height matrix.Scale( NCustomTextureMappingExample.RectWidth / (2.0 * imgWidth), NCustomTextureMappingExample.RectHeight / (3.0 * imgHeight)); // Rotate the image to the specified angle matrix.Rotate(m_TextureMapping.TextureAngle * NAngle.Degree2Rad); // Translate the image to the specfied pin point matrix.Translate(m_TextureMapping.PinPoint.X, m_TextureMapping.PinPoint.Y); return(matrix); }
public void Test1() { IMatrix <double> mat = new NMatrix(new double[, ] { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } }); //IMatrix<double> mat2 = mat.Multiply(IdentityMatrix.CreateNew(3)); IMatrix <double> mat2 = mat.Multiply(mat); IMatrix <double> mat3 = mat2.Add(10); System.Console.WriteLine(mat); System.Console.WriteLine(); System.Console.WriteLine(mat2); System.Console.WriteLine(); System.Console.WriteLine(mat3); }
private void OnPrintPage(NPrintDocument sender, NPrintPageEventArgs e) { NSize pageSizeDIP = new NSize(this.Width, this.Height); try { NMargins pageMargins = NMargins.Zero; NRegion clip = NRegion.FromRectangle(new NRectangle(0, 0, e.PrintableArea.Width, e.PrintableArea.Height)); NMatrix transform = new NMatrix(e.PrintableArea.X, e.PrintableArea.Y); NPaintVisitor visitor = new NPaintVisitor(e.Graphics, 300, transform, clip); // forward traverse the display tree this.OwnerWindow.VisitDisplaySubtree(visitor); e.HasMorePages = false; } catch (Exception x) { NMessageBox.Show(x.Message, "Exception", ENMessageBoxButtons.OK, ENMessageBoxIcon.Error); } }
public Line GetLine(PointUV pointUV) { var unitMatrix = new NMatrix(new double[, ] { { pointUV.U }, { pointUV.V }, { 1 } }); NMatrix solution; if (!NMatrix.TryGaussJordanElimination(Homography, unitMatrix, out solution)) { throw new ArgumentException(); } //a = Vector.Create(solution[0, 3], solution[1, 3], solution[2, 3]); //b = Vector.Create(solution[0, 4], solution[1, 4], solution[2, 4]); ////var vector = Vector.Create(pointUV.U * a.X, pointUV.V * a.Y, a.Z); //return Line.Create(Point.Origin + a, b.Direction); return(Line.Create(Point.Origin, Direction.Create( solution[0, 4] / (solution[0, 3] + 1), solution[1, 4] / (solution[1, 3] + 1), solution[2, 4] / (solution[2, 3] + 1) ))); }
protected void OnPrintPage(NPrintDocument sender, NPrintPageEventArgs e) { NSize pageSizeDIP = new NSize(this.Width, this.Height); try { double clipW = e.PrintableArea.Width; double clipH = e.PrintableArea.Height; NRegion clip = NRegion.FromRectangle(new NRectangle(0, 0, clipW, clipH)); NMatrix transform = new NMatrix(e.PrintableArea.X, e.PrintableArea.Y); NPaintVisitor visitor = new NPaintVisitor(e.Graphics, 300, transform, clip); // forward traverse the display tree VisitDisplaySubtree(visitor); e.HasMorePages = false; } catch (Exception ex) { NMessageBox.Show(null, ex.Message, "Exception", ENMessageBoxButtons.OK, ENMessageBoxIcon.Error); } }
public void Calibrate() { //CalibrationPoints.Add(PointUV.Create(-100, -100)); //CalibrationPoints.Add(PointUV.Create(-100, 100)); //CalibrationPoints.Add(PointUV.Create(100, -100)); //CalibrationPoints.Add(PointUV.Create(100, 100)); //CalibrationPoints.Add(PointUV.Create(-80, -80)); //CalibrationPoints.Add(PointUV.Create(-80, 80)); //CalibrationPoints.Add(PointUV.Create(80, -80)); //CalibrationPoints.Add(PointUV.Create(80, 80)); double h = (double)imageSize.Height; CalibrationPoints.Add(PointUV.Create(0, 0)); CalibrationPoints.Add(PointUV.Create(0, h)); CalibrationPoints.Add(PointUV.Create(h, 0)); CalibrationPoints.Add(PointUV.Create(h, h)); h *= 2; CalibrationPoints.Add(PointUV.Create(0, 0)); CalibrationPoints.Add(PointUV.Create(0, h)); CalibrationPoints.Add(PointUV.Create(h, 0)); CalibrationPoints.Add(PointUV.Create(h, h)); NMatrix calibrationMatrixA = new NMatrix(2 * CalibrationPoints.Count, 11); NMatrix calibrationMatrixB = new NMatrix(2 * CalibrationPoints.Count, 1); for (int i = 0; i < CalibrationPoints.Count; i++) { double x = controlForm.CalibrationPoints[i].X; double y = controlForm.CalibrationPoints[i].Y; double z = controlForm.CalibrationPoints[i].Z; double u = CalibrationPoints[i].U; double v = CalibrationPoints[i].V; calibrationMatrixA[2 * i, 0] = x; calibrationMatrixA[2 * i, 1] = y; calibrationMatrixA[2 * i, 2] = z; calibrationMatrixA[2 * i, 3] = 1; calibrationMatrixA[2 * i, 8] = -u * x; calibrationMatrixA[2 * i, 9] = -u * y; calibrationMatrixA[2 * i, 10] = -u * z; calibrationMatrixA[2 * i + 1, 4] = x; calibrationMatrixA[2 * i + 1, 5] = y; calibrationMatrixA[2 * i + 1, 6] = z; calibrationMatrixA[2 * i + 1, 7] = 1; calibrationMatrixA[2 * i + 1, 8] = -v * x; calibrationMatrixA[2 * i + 1, 9] = -v * y; calibrationMatrixA[2 * i + 1, 10] = -v * z; calibrationMatrixB[2 * i, 0] = u; calibrationMatrixB[2 * i + 1, 0] = v; } NMatrix calibrationMatrixAT = NMatrix.Transpose(calibrationMatrixA); NMatrix homographyData = NMatrix.Inverse(calibrationMatrixAT * calibrationMatrixA) * calibrationMatrixAT * calibrationMatrixB; Homography = new NMatrix(new double[, ] { { homographyData[0, 0], homographyData[1, 0], homographyData[2, 0], homographyData[3, 0] }, { homographyData[4, 0], homographyData[5, 0], homographyData[6, 0], homographyData[7, 0] }, { homographyData[8, 0], homographyData[9, 0], homographyData[10, 0], 1 } }); }
public void Matraces_Test() { NMatrix matrix = new NMatrix(new decimal[2, 2] { { 1, 0 }, { 0, 1 } }); Assert.AreEqual(1, matrix.Determinant()); Assert.AreEqual(4, (matrix * 2).Determinant()); NMatrix test = matrix.T(); Assert.IsTrue(matrix == matrix.T()); Assert.IsTrue(matrix == matrix.I()); NMatrix A = new NMatrix(new double[2, 2] { { 2, 4 }, { 7, 5 } }); NMatrix A_T = A.T(); Assert.AreEqual(new NMatrix(new double[2, 2] { { 2, 7 }, { 4, 5 } }), A_T); NMatrix A_I = A.I(); NMatrix A_adjoint = A.Adjoint(); NMatrix A_inverse = A_adjoint / A.Determinant(); NMatrix A_result = A * A_inverse; Assert.AreEqual(A_I, A_result); NMatrix B = new NMatrix(new decimal[2, 2] { { 2, 4 }, { 1, 5 } }); NMatrix B_T = B.T(); Assert.AreEqual(new NMatrix(new decimal[2, 2] { { 2, 1 }, { 4, 5 } }), B_T); NMatrix B_I = B.I(); NMatrix B_adjoint = B.Adjoint(); NMatrix B_inverse = B_adjoint / B.Determinant(); NMatrix B_result = B * B_inverse; Assert.AreEqual(B_I, B_result); NMatrix C = new NMatrix(new double[3, 3] { { 13, 8, -12 }, { 11, 20, 6 }, { 3, -8, 15 } }); NMatrix C_T = C.T(); Assert.AreEqual(new NMatrix(new double[3, 3] { { 13, 11, 3 }, { 8, 20, -8 }, { -12, 6, 15 } }), C_T); NMatrix C_I = C.I(); NMatrix C_adjoint = C.Adjoint(); NMatrix C_inverse = C_adjoint / C.Determinant(); NMatrix C_result = C * C_inverse; Assert.AreEqual(C_I, C_result); NMatrix D = new NMatrix(new double[3, 3] { { 255, -98, 11 }, { 45, 67, 59 }, { -15, 36, -20 } }); Print(D.ToStringWithBrackets()); NMatrix D_T = D.T(); Print(D_T.ToStringWithBrackets()); Assert.AreEqual(new NMatrix(new double[3, 3] { { 255, 45, -15 }, { -98, 67, 36 }, { 11, 59, -20 } }), D_T); NMatrix D_I = D.I(); Print(D_I.ToStringWithBrackets()); NMatrix D_adjoint = D.Adjoint(); Print(D_adjoint.ToStringWithBrackets()); NMatrix D_inverse = D_adjoint / D.Determinant(); Print(D_inverse.ToStringWithBrackets()); NMatrix D_result = D * D_inverse; Print(D_result.ToStringWithBrackets()); Assert.AreEqual(D_I, D_result); Assert.IsFalse(D_I.EqualsPrecision(D_result, 24)); }
void QP_Solve(NMatrix AMatrix, NVector bVector, ref NVector fVector) { //I'm unable to find a good way of solving QP problems for now. I'm going to assume that since }
/// <summary> /// Creates a custom shape that is essentially a group consisting of three other shapes each with different filling. /// You need to use groups to have shapes that mix different fill, or stroke styles. /// </summary> /// <returns></returns> protected NShape CreateCoffeeCupShape() { // create the points and paths from which the shape consits NPoint[] cupPoints = new NPoint[] { new NPoint(45, 268), new NPoint(63, 331), new NPoint(121, 331), new NPoint(140, 268) }; NGraphicsPath handleGraphicsPath = new NGraphicsPath(); handleGraphicsPath.AddClosedCurve(new NPoint[] { new NPoint(175, 295), new NPoint(171, 278), new NPoint(140, 283), new NPoint(170, 290), new NPoint(128, 323) }, 1); NGraphicsPath steamGraphicsPath = new NGraphicsPath(); steamGraphicsPath.AddCubicBeziers(new NPoint[] { new NPoint(92, 270), new NPoint(53, 163), new NPoint(145, 160), new NPoint(86, 50), new NPoint(138, 194), new NPoint(45, 145), new NPoint(92, 270) }); steamGraphicsPath.CloseFigure(); // calculate some bounds NRectangle handleBounds = handleGraphicsPath.ExactBounds; NRectangle cupBounds = NGeometry2D.GetBounds(cupPoints); NRectangle steamBounds = steamGraphicsPath.ExactBounds; NRectangle geometryBounds = NRectangle.Union(cupBounds, handleBounds, steamBounds); // normalize the points and paths by transforming them to relative coordinates NRectangle normalRect = new NRectangle(0, 0, 1, 1); NMatrix transform = NMatrix.CreateBoundsStretchMatrix(geometryBounds, normalRect); transform.TransformPoints(cupPoints); handleGraphicsPath.Transform(transform); steamGraphicsPath.Transform(transform); // create the cup shape NDrawPolygon cupPolygon = new NDrawPolygon(normalRect, cupPoints); cupPolygon.Relative = true; NShape cupShape = new NShape(); cupShape.Init2DShape(); cupShape.Geometry.Fill = new NColorFill(NColor.Brown); cupShape.Geometry.Add(cupPolygon); cupShape.SetBounds(geometryBounds); // create the cup handle NDrawPath handlePath = new NDrawPath(normalRect, handleGraphicsPath); handlePath.Relative = true; NShape handleShape = new NShape(); handleShape.Init2DShape(); handleShape.Geometry.Fill = new NColorFill(NColor.LightSalmon); handleShape.Geometry.Add(handlePath); handleShape.SetBounds(geometryBounds); // create the steam NDrawPath steamPath = new NDrawPath(steamGraphicsPath.Bounds, steamGraphicsPath); steamPath.Relative = true; NShape steamShape = new NShape(); steamShape.Init2DShape(); steamShape.Geometry.Fill = new NColorFill(new NColor(50, 122, 122, 122)); steamShape.Geometry.Add(steamPath); steamShape.SetBounds(geometryBounds); // group the shapes as a single group NGroup group; NBatchGroup batch = new NBatchGroup(m_DrawingDocument); batch.Build(cupShape, handleShape, steamShape); batch.Group(null, out group); // alter some properties of the group group.SelectionMode = ENGroupSelectionMode.GroupOnly; group.SnapToShapes = false; return(group); }