private bool showCirc() { block = Block.Construct(); for (int i = 1; i < copCount; ++i) { GeoObjectList li = new GeoObjectList(); // für jede Kopie ein Clone machen li = originals.CloneObjects(); ModOp m = ModOp.Rotate(rotationPoint, base.ActiveDrawingPlane.Normal, i * copAngle); if (!objRot) // Objekte drehen mit: einfach modifizieren { li.Modify(m); } else { // Objekte drehen nicht mit: Translation des gedrehten centerpoints ModOp mt = ModOp.Translate(new GeoVector(centerPoint, m * centerPoint)); li.Modify(mt); } block.Add(li); } if (block.Count > 0) { base.ActiveObject = block; return(true); } else { base.ActiveObject = null; return(false); } }
private void RotateWithPlanes() { // get rotation axis from the two planes if (src.Intersect(trg, out GeoPoint loc, out GeoVector dir)) { // set to original position for (int i = 0; i < block.Count; ++i) { block.Child(i).CopyGeometry(originals[i]); } Plane perp = new Plane(loc, dir); // plane perpendicular to rotation axis GeoVector2D from = perp.Project(dir ^ src.Normal); GeoVector2D to = perp.Project(dir ^ trg.Normal); SweepAngle sw = new SweepAngle(from, to); rotationAngle = sw; rotAngleInput.ForceValue(rotationAngle); ModOp m0 = ModOp.Rotate(loc, dir, sw); ModOp m1 = ModOp.Rotate(loc, -dir, sw); GeoVector n0 = m0 * src.Normal; GeoVector n1 = m1 * src.Normal; ModOp m; // not sure, which rotation is better if (Math.Abs(n0 * trg.Normal) > Math.Abs(n1 * trg.Normal)) { m = ModOp.Rotate(loc, dir, sw + GetOffset()); axisVector = dir; } else { m = ModOp.Rotate(loc, -dir, sw + GetOffset()); axisVector = -dir; } block.Modify(m); base.BasePoint = loc; } }
public override void OnDone() { // ist die Shift Taste gehalten, so werden Kopien gemacht, d.h. der die Elemente // des blocks werden eingefügt. Ansonsten werden die original-Objekte verändert // TODO: Feedback über Cursor bei Shift-Taste fehlt noch // TODO: die neuen oder veränderten Objekte sollten markiert sein. using (Frame.Project.Undo.UndoFrame) { // ModOp m = ModOp.Rotate(base.BasePoint,base.ActiveDrawingPlane.Normal,new SweepAngle(rotationAngle)); ModOp m = ModOp.Rotate(base.BasePoint, axisVector, new SweepAngle(rotationAngle) + GetOffset()); if (((Frame.UIService.ModifierKeys & Keys.Shift) != 0) || copyObject) { GeoObjectList cloned = new GeoObjectList(); foreach (IGeoObject go in originals) { IGeoObject cl = go.Clone(); cl.Modify(m); cloned.Add(cl); } base.Frame.Project.GetActiveModel().Add(cloned); } else { originals.Modify(m); } } base.ActiveObject = null; // damit es nicht gleich eingefügt wird base.OnDone(); }
/// <summary> /// Overrides <see cref="CADability.GeoObject.ISurfaceImpl.PointAt (GeoPoint2D)"/> /// </summary> /// <param name="uv"></param> /// <returns></returns> public override GeoPoint PointAt(GeoPoint2D uv) { double pos = GetPos(uv.y); GeoPoint2D p2d = basisCurve2D.PointAt(pos); ModOp rot = ModOp.Rotate(1, (SweepAngle)uv.x); ModOp movePitch = ModOp.Translate(0, pitch * uv.x / (Math.PI * 2.0), 0); return(toSurface * movePitch * rot * p2d); }
/// <summary> /// Overrides <see cref="CADability.GeoObject.ISurfaceImpl.FixedU (double, double, double)"/> /// </summary> /// <param name="u"></param> /// <param name="vmin"></param> /// <param name="vmax"></param> /// <returns></returns> public override ICurve FixedU(double u, double vmin, double vmax) { ICurve2D btr = basisCurve2D.Trim(GetPos(vmin), GetPos(vmax)); ICurve b3d = btr.MakeGeoObject(Plane.XYPlane) as ICurve; ModOp rot = ModOp.Rotate(1, (SweepAngle)u); ModOp movePitch = ModOp.Translate(0, pitch * u / (Math.PI * 2.0), 0); return(b3d.CloneModified(toSurface * movePitch * rot)); }
private void ReflectLineChanged(CurveInput sender, ICurve SelectedCurve) { for (int i = 0; i < originals.Count; ++i) { // Urzustand block.Item(i).CopyGeometry(originals[i]); } // nun drehen um 180 Grad reflectModOp = ModOp.Rotate(SelectedCurve.StartPoint, SelectedCurve.StartDirection, new SweepAngle(Math.PI)); block.Modify(reflectModOp); }
private bool OnSetRotationAngle(Angle angle) { ModOp m = ModOp.Rotate(base.BasePoint, axisVector, new SweepAngle(angle - rotationAngle) + GetOffset()); block.Modify(m); base.ActiveObject = block; rotationAngle = angle; return(true); }
private void OnSetLatitude(Angle a) { GeoVector l = Frame.ActiveView.Projection.DrawingPlane.ToLocal(GetGeoVector()); GeoVector nl = new GeoVector(l.x, l.y, 0); nl.Length = l.Length; ModOp rot = ModOp.Rotate(nl ^ Frame.ActiveView.Projection.DrawingPlane.Normal, a); // cross product correct? SetValue(Frame.ActiveView.Projection.DrawingPlane.ToGlobal(rot * nl), true); }
/// <summary> /// Overrides <see cref="CADability.GeoObject.ISurfaceImpl.VDirection (GeoPoint2D)"/> /// </summary> /// <param name="uv"></param> /// <returns></returns> public override GeoVector VDirection(GeoPoint2D uv) { double pos = GetPos(uv.y); GeoVector2D dir = basisCurve2D.DirectionAt(pos); //dir = (1.0 / (curveEndParameter - curveStartParameter)) * dir; // dir ist die Änderung um 1 also volle Kurvenlänge // 15.8.17: die Skalierung von dir ist wohl falsch: NewtonLineintersection läuft mit obiger Zeile nicht richtig, so aber perfekt // pitch fehlt noch, ist vermutlich nicht nötig ModOp rot = ModOp.Rotate(1, (SweepAngle)uv.x); return(toSurface * rot * dir); }
private void OnSetEndPoint(GeoPoint p) { endPoint = p; if (startPointInput.Fixed) { rotAngleInput.Fixed = true; // damit die Aktion nach dem Endpunkt aufhört SweepAngle swAngle = new SweepAngle((GeoVector2D)(base.ActiveDrawingPlane.Project(startPoint) - base.ActiveDrawingPlane.Project(refPoint)), base.ActiveDrawingPlane.Project(endPoint) - base.ActiveDrawingPlane.Project(refPoint)); ModOp m = ModOp.Rotate(base.BasePoint, axisVector, new SweepAngle(swAngle - rotationAngle) + GetOffset()); rotationAngle = swAngle.Radian; block.Modify(m); feedBackEllipse.SetArcPlaneCenterStartEndPoint(ActiveDrawingPlane, ActiveDrawingPlane.Project(BasePoint), ActiveDrawingPlane.Project(startPoint), ActiveDrawingPlane.Project(endPoint), ActiveDrawingPlane, swAngle.Radian > 0.0); } }
private void RotateLineChanged(CurveInput sender, ICurve SelectedCurve) { base.BasePoint = SelectedCurve.StartPoint; axisVector = SelectedCurve.StartDirection; // erstmal den Urprungszustand herstellen for (int i = 0; i < block.Count; ++i) { block.Child(i).CopyGeometry(originals[i]); } ModOp m = ModOp.Rotate(base.BasePoint, axisVector, new SweepAngle(rotationAngle) + GetOffset()); block.Modify(m); }
private void SetRefPoint(GeoPoint p) { refPoint = p; block.RefPoint = p; base.BasePoint = p; // für die Winkelberechnung if (rotAngleInput.Fixed) { for (int i = 0; i < block.Count; ++i) { block.Child(i).CopyGeometry(originals[i]); } ModOp m = ModOp.Rotate(base.BasePoint, axisVector, new SweepAngle(rotationAngle) + GetOffset()); block.Modify(m); } }
private bool RotateLine(CurveInput sender, ICurve[] Curves, bool up) { // ... nur die sinnvolen Kurven verwenden ArrayList usableCurves = new ArrayList(); ModOp m; for (int i = 0; i < Curves.Length; ++i) { Line l = Curves[i] as Line; if (l != null) { usableCurves.Add(Curves[i]); } } // ...hier wird der ursprüngliche Parameter überschrieben. Hat ja keine Auswirkung nach außen. Curves = (ICurve[])usableCurves.ToArray(typeof(ICurve)); if (up) { if (Curves.Length == 0) { sender.SetCurves(Curves, null); // ...die werden jetzt im ControlCenter dargestellt (nur bei up) } else { // erst jetzt die Werte merken! base.BasePoint = Curves[0].StartPoint; axisVector = Curves[0].StartDirection; sender.SetCurves(Curves, Curves[0]); } } // erstmal den Urprungszustand herstellen, da sonst Drehungg akkumuliert wird for (int i = 0; i < block.Count; ++i) { block.Child(i).CopyGeometry(originals[i]); } if (Curves.Length > 0) { // einfach die erste Kurve nehmen ICurve iCurve = Curves[0]; m = ModOp.Rotate(iCurve.StartPoint, iCurve.StartDirection, new SweepAngle(rotationAngle) + GetOffset()); block.Modify(m); return(true); } // rückgängig! m = ModOp.Rotate(base.BasePoint, axisVector, new SweepAngle(rotationAngle) + GetOffset()); block.Modify(m); return(false); }
private bool ReflectLine(CurveInput sender, ICurve[] Curves, bool up) { // ... nur die sinnvolen Kurven verwenden ArrayList usableCurves = new ArrayList(); for (int i = 0; i < Curves.Length; ++i) { Line l = Curves[i] as Line; if (l != null) { usableCurves.Add(Curves[i]); } } // ...hier wird der ursprüngliche Parameter überschrieben. Hat ja keine Auswirkung nach außen. Curves = (ICurve[])usableCurves.ToArray(typeof(ICurve)); if (up) { if (Curves.Length == 0) { sender.SetCurves(Curves, null); // ...die werden jetzt im ControlCenter dargestellt (nur bei up) OnDone(); return(true); } else { sender.SetCurves(Curves, Curves[0]); } } for (int i = 0; i < originals.Count; ++i) { // Urzustand block.Item(i).CopyGeometry(originals[i]); } if (Curves.Length > 0) { // einfach die erste Kurve nehmen ICurve iCurve = Curves[0]; // nun drehen um 180 Grad reflectModOp = ModOp.Rotate(iCurve.StartPoint, iCurve.StartDirection, new SweepAngle(Math.PI)); block.Modify(reflectModOp); return(true); } reflectModOp = reflectModOpStart; // zurücksetzen block.Modify(reflectModOp); return(false); }
public override void Derivation2At(GeoPoint2D uv, out GeoPoint location, out GeoVector du, out GeoVector dv, out GeoVector duu, out GeoVector dvv, out GeoVector duv) { location = PointAt(uv); du = UDirection(uv); dv = VDirection(uv); double pos = GetPos(uv.y); GeoPoint2D p2d = basisCurve2D.PointAt(pos); duu = new GeoVector(-Math.Cos(uv.x), 0.0, -Math.Sin(uv.x)); GeoVector2D deriv1, deriv2; if (basisCurve2D.TryPointDeriv2At(pos, out p2d, out deriv1, out deriv2)) { ModOp rot = ModOp.Rotate(1, (SweepAngle)uv.x); dvv = toSurface * rot * deriv2; duv = GeoVector.NullVector; } else { dvv = GeoVector.NullVector; duv = GeoVector.NullVector; } }
private bool rotateOrg() { if (selectedObjectsList == null) { return(false); } IGeoObject iGeoObjectSel; blk = Block.Construct(); // zur Darstellung if (base.ActiveObject != null) { blk.CopyAttributes(base.ActiveObject); } // der block wird das neue aktive Objekt, er muss die Attribute tragen, weil sie später // wieder von ihm verlangt werden Boolean success = false; // hat er wenigstens eins gefunden for (int i = 0; i < selectedObjectsList.Count; i++) // läuft über alle selektierten Objekte. Evtl nur eins bei Konstruktion { iGeoObjectSel = selectedObjectsList[i]; // zur Vereinfachung geoObjectOrgList[i] = iGeoObjectSel; // zum Weglöschen des Originals in onDone ownerList[i] = iGeoObjectSel.Owner; // owner merken für löschen pathCreatedFromModelList[i] = null; shapeList[i] = null; Path p = null; if (iGeoObjectSel is ICurve) { p = CADability.GeoObject.Path.CreateFromModel(iGeoObjectSel as ICurve, Frame.ActiveView.Model, Frame.ActiveView.Projection, true); if (p == null) { // also nur Einzelelement if (iGeoObjectSel is Path) { // schon fertig p = iGeoObjectSel.Clone() as Path; } else { // Pfad aus Einzelobjekt machen: p = Path.Construct(); p.Set(new ICurve[] { iGeoObjectSel.Clone() as ICurve }); } } else { // CreateFromModel hat was zusammengesetzt geoObjectOrgList[i] = null; // zum nicht Weglöschen des Originals in onDone pathCreatedFromModelList[i] = p; // kopie merken für onDone p = p.Clone() as Path; p.Flatten(); } if (p != null) { // if (angleOffsetRotation != 0.0) { ModOp m = ModOp.Rotate(axisPoint, axisVector, new SweepAngle(angleOffsetRotation)); p.Modify(m); } double sw = angleRotation; if (sw == 0.0) { sw = Math.PI * 2.0; } IGeoObject shape = Make3D.MakeRevolution(p, axisPoint, axisVector, sw, Frame.Project); if (shape != null) { shape.CopyAttributes(blk); // die Attribute müssen vom Block übernommen werden shapeList[i] = shape; // fertiger Körper in shapeList blk.Add(shape); // zum Darstellen base.FeedBack.AddSelected(p); // zum Markieren des Ursprungsobjekts success = true; } } } } if (success) { base.ActiveObject = blk; // darstellen base.ShowActiveObject = true; return(true); } else { optionalOrg(); base.ShowActiveObject = false; base.FeedBack.ClearSelected(); return(false); } }
public override void OnMouseMove(MouseEventArgs e, IView vw) { if (e.Button != MouseButtons.Left) { return; } if (modelView == null) { return; } int HOffset = e.X - lastPanPosition.X; int VOffset = e.Y - lastPanPosition.Y; if (VOffset != 0 || HOffset != 0) { Projection Projection = vw.Projection; lastPanPosition = new Point(e.X, e.Y); GeoVector haxis = Projection.InverseProjection * GeoVector.XAxis; GeoVector vaxis = Projection.InverseProjection * GeoVector.YAxis; ModOp mh = ModOp.Rotate(vaxis, SweepAngle.Deg(HOffset / 5.0)); ModOp mv = ModOp.Rotate(haxis, SweepAngle.Deg(VOffset / 5.0)); ModOp project = Projection.UnscaledProjection * mv * mh; // jetzt noch die Z-Achse einrichten. Die kann senkrecht nach oben oder unten // zeigen. Wenn die Z-Achse genau auf den Betrachter zeigt oder genau von ihm weg, // dann wird keine Anpassung vorgenommen, weils sonst zu sehr wackelt GeoVector z = project * GeoVector.ZAxis; if (modelView.ZAxisUp) { const double mindeg = 0.05; // nur etwas aufrichten, aber in jedem Durchlauf if (z.y < -0.1) { // Z-Achse soll nach unten zeigen Angle a = new Angle(-GeoVector2D.YAxis, new GeoVector2D(z.x, z.y)); if (a.Radian > mindeg) { a.Radian = mindeg; } if (a.Radian < -mindeg) { a.Radian = -mindeg; } if (z.x < 0) { project = project * ModOp.Rotate(vaxis ^ haxis, -a.Radian); } else { project = project * ModOp.Rotate(vaxis ^ haxis, a.Radian); } z = project * GeoVector.ZAxis; } else if (z.y > 0.1) { Angle a = new Angle(GeoVector2D.YAxis, new GeoVector2D(z.x, z.y)); if (a.Radian > mindeg) { a.Radian = mindeg; } if (a.Radian < -mindeg) { a.Radian = -mindeg; } if (z.x < 0) { project = project * ModOp.Rotate(vaxis ^ haxis, a.Radian); } else { project = project * ModOp.Rotate(vaxis ^ haxis, -a.Radian); } z = project * GeoVector.ZAxis; } } // Fixpunkt bestimmen Point clcenter = vw.Canvas.ClientRectangle.Location; clcenter.X += vw.Canvas.ClientRectangle.Width / 2; clcenter.Y += vw.Canvas.ClientRectangle.Height / 2; // ium Folgenden ist Temporary auf true zu setzen und ein Mechanismus zu finden // wie der QuadTree von ProjektedModel berechnet werden soll //GeoVector newDirection = mv * mh * Projection.Direction; //GeoVector oldDirection = Projection.Direction; //GeoVector perp = oldDirection ^ newDirection; GeoPoint fixpoint; //if (Settings.GlobalSettings.ContainsSetting("ViewFixPoint")) if (modelView != null && modelView.FixPointValid) { //fixpoint = (GeoPoint)Settings.GlobalSettings.GetValue("ViewFixPoint"); fixpoint = modelView.FixPoint; } else { fixpoint = Projection.UnProject(clcenter); } modelView.SetViewDirection(project, fixpoint, true); if (Math.Abs(HOffset) > Math.Abs(VOffset)) { if (HOffset > 0) { vw.Canvas.Cursor = "PanEast"; } else { vw.Canvas.Cursor = "PanWest"; } } else { if (HOffset > 0) { vw.Canvas.Cursor = "PanSouth"; } else { vw.Canvas.Cursor = "PanNorth"; } } modelView.projectedModelNeedsRecalc = false; } }
ModOp IMovement.GetPosition(double u) { return(ModOp.Rotate(axis.Location, axis.Direction, new SweepAngle(u))); }
/// <summary> /// Constructs a non periodic spherical surface with <paramref name="center"/> and <paramref name="radius"/>. The z-axis will be oriented /// so that the "south pole" falls into an unused part of the sphere. The edges are <paramref name="orientedCurves"/> bound the sphere /// so that when you walk along the curve (<paramref name="outwardOriented"/>==true: on the outside, false: on the inside of the sphere), the /// used surfaces is on the left side of the curve. The curves must all be connected and define one or more closed loops on the surface. /// </summary> /// <param name="center"></param> /// <param name="radius"></param> /// <param name="outwardOriented">true: the center is on the inside, false: the center is on the outside of the surface</param> /// <param name="orientedCurves"></param> public SphericalSurfaceNP(GeoPoint center, double radius, bool outwardOriented, ICurve[] orientedCurves) { // find all intersection points of the curves with a plane through the center // the points must be on a circle (because the curves are on the sphere) and alternating enter and leave the used surface. // we look for the biggest part outside the surface and use its center as the south pole for (int ii = 0; ii < 2; ii++) { // if the first loop doesn't find a solution, run with different points again // exactly 3 arcs, which define an octant of the sphere can make a problem for (int i = 0; i < orientedCurves.Length; i++) { double pos = 0.45; if (ii == 1) { pos = 0.55; } GeoPoint p = orientedCurves[i].PointAt(pos); // not exactly in the middle to avoid special cases GeoVector dir = orientedCurves[i].DirectionAt(pos); GeoVector xdir = p - center; Plane pln; if (outwardOriented) { pln = new Plane(center, xdir, dir ^ xdir); } else { pln = new Plane(center, xdir, xdir ^ dir); } if (ii == 1) { pln.Modify(ModOp.Rotate(center, xdir, SweepAngle.Deg(5))); // slightly rotate to not go exactly through a vertex } double[] pi = orientedCurves[i].GetPlaneIntersection(pln); SortedDictionary <double, bool> positions = new SortedDictionary <double, bool>(); bool ok = false; for (int j = 0; j < pi.Length; j++) { GeoPoint2D pi2d = pln.Project(orientedCurves[i].PointAt(pi[j])); double a = Math.Atan2(pi2d.y, pi2d.x); if (Math.Abs(pi[j] - pos) < 1e-6) { ok = true; a = 0.0; } if (positions.ContainsKey(a)) { ok = false; break; } else { positions[a] = outwardOriented ^ (pln.ToLocal(orientedCurves[i].DirectionAt(pi[j])).z > 0); } } if (ok) { for (int k = 0; k < orientedCurves.Length; k++) { if (k == i) { continue; } pi = orientedCurves[k].GetPlaneIntersection(pln); for (int j = 0; j < pi.Length; j++) { GeoPoint2D pi2d = pln.Project(orientedCurves[k].PointAt(pi[j])); double a = Math.Atan2(pi2d.y, pi2d.x); if (a < 0) { a += Math.PI * 2.0; } if (positions.ContainsKey(a)) { ok = false; break; } else { positions[a] = outwardOriented ^ (pln.ToLocal(orientedCurves[k].DirectionAt(pi[j])).z > 0); } } if (!ok) { break; // two identical intersection points } } } if (ok) { double lastPos = -1; bool lastEnter = false; double sp = 0, d = double.MinValue; foreach (KeyValuePair <double, bool> position in positions) { if (lastPos >= 0) { if (position.Value == lastEnter) { ok = false; // must be alternating break; } if (position.Value && position.Key - lastPos > d) { d = position.Key - lastPos; sp = lastPos; } } lastPos = position.Key; lastEnter = position.Value; } GeoPoint2D soutPole2d = new GeoPoint2D(radius * Math.Cos(sp + d / 2), radius * Math.Sin(sp + d / 2)); if (ok && d > double.MinValue) { this.center = center; zAxis = center - pln.ToGlobal(soutPole2d); zAxis.ArbitraryNormals(out xAxis, out yAxis); if (!outwardOriented) { xAxis = -xAxis; } xAxis.Length = zAxis.Length; yAxis.Length = zAxis.Length; } else { ok = false; } } #if DEBUG // GeoObjectList dbg = DebugGrid; #endif if (ok) { return; } } } }