Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: set / update RectangleShape size and Sprite rotation (prepare for Math)  (Read 1716 times)

0 Members and 1 Guest are viewing this topic.

globalenemy

  • Newbie
  • *
  • Posts: 10
    • View Profile
Hello,
I'm drawing a Line by placing (drawables I've created) 2 Vertice Objects and an Edge Object with a mouse click at mouse position, then when moving the mouse I move the 2nd vertice to the mouse position. A 2nd mouse click releases the 2nd vertice.

While the 2nd vertice is being moved the Width of the RectangleShape of the Edge Object and the Rotation of the drawing Sprite of the Edge Object need to be updated.

Creating the Edge works fine but applying new distance and rotation doesn't. Well sort of. Something is generally wrong with the way I get the rotation angle, but that shouldn't also fiddle with the distance.

For clearance, the way i draw:
Control : Transformable, Drawable (containing a Sprite, a RenderTexture and a List<Drawable>
   Each Update all Drawables are drawn to the RenderTexture which is shown with the Sprite.
Edge : Control (containing a RectangleShape in the List<Drawables> and links to two Vertices)

http://gfycat.com/ThoroughBetterBarebirdbat
first Edge (Vertice A at lower left, Vertice B at upper right)
second Edge (Vertice A at upper right, Vertice B at lower left)
third Edge: placement demonstration

I know it could be that just my math is wrong but when I fiddle with sprites and shapes in sfml I allways step into problems like this. Maybe you see what's wrong here?

I'm coding DotNet:

//Control Creator
public Control(uint _width, uint _height) {
   enabled = true;
   visible = true;
   hovered = false;
   pressed = false;
   surface = new RenderTexture(_width, _height);
   drawables = new List<Drawable>();
   sprite = new Sprite(surface.Texture);
   sprite.Position = Position;
   sprite.Origin = Origin;
   clearColor = defaultClearColor;
}

//Control manipulation
public virtual void SetSize(Vector2u _size) {
   surface = new RenderTexture(_size.X, _size.Y);
   sprite = new Sprite(surface.Texture);
   sprite.Position = Position;
   sprite.Origin = Origin;
}
public void SetPosition(Vector2f _position) {
   Position = _position;
   sprite.Position = _position;
}
public void SetOrigin(Vector2f _origin) {
   Origin = _origin;
   sprite.Origin = _origin;
}
public void SetRotation(float _angle) {
   Rotation = _angle;
   sprite.Rotation = _angle;
}

//Edge Creator
public Edge(Vertice _a, Vertice _b) : base(0, 0) {
   _a.Edges.Add(this);
   _b.Edges.Add(this);
   a = _a;
   b = _b;
   thickness = defThickness;
   color = defColor;

   float distance = (float)Vertice.Distance(a, b);
   base.SetSize(new Vector2u((uint)distance, (uint)thickness));
   SetPosition(a.Position);
   SetOrigin(new Vector2f(0, thickness / 2));
   float angle = (float)Vertice.Angle(a, b);
   SetRotation(angle);
   shape = new RectangleShape(new Vector2f(distance, thickness));
   shape.FillColor = color;
   Drawables.Add(shape);
}

//Edge manipulation
public void SetVerticeA(Vertice _a) {
   if (_a != a && a != null) a.Edges.Remove(this);
   if (!_a.Edges.Contains(this)) _a.Edges.Add(this);
   a = _a;

   float distance = (float)Vertice.Distance(a, b);
   base.SetSize(new Vector2u((uint)distance, (uint)thickness));
   SetPosition(a.Position);
   SetOrigin(new Vector2f(0, thickness / 2));
   float angle = (float)Vertice.Angle(a, b);
   SetRotation(angle);
   shape.Size = new Vector2f(distance, thickness);
}
public void SetVerticeB(Vertice _b) {
   if (_b != b && b != null) b.Edges.Remove(this);
   if (!_b.Edges.Contains(this)) _b.Edges.Add(this);
   b = _b;

   float distance = (float)Vertice.Distance(a, b);
   base.SetSize(new Vector2u((uint)distance, (uint)thickness));
   float angle = (float)Vertice.Angle(a, b);
   SetRotation(angle);
   shape.Size = new Vector2f(distance, thickness);
}

Math:
public static double Distance(Vertice _a, Vertice _b) {
   return Math.Sqrt(Math.Pow((_a.X - _a.Y), 2) + Math.Pow((_b.X - _b.Y), 2));
}
public static double Angle(Vertice _a, Vertice _b) {
   double radians = Math.Atan((_b.Y - _a.Y) / (_b.X - _a.X));
   return  radians * 180 / Math.PI;
}

MouseHandling:
private void WindowOnMouseClick(object sender, EventArgs e) {
   if (!inPlacement) {
      inPlacement = true;

      SFML.System.Vector2i mouse = SFML.Window.Mouse.GetPosition(window.Real);
      placementA = new Vertice(new SFML.System.Vector2f(mouse.X, mouse.Y));
      placementA.SetEnabled(false);
      placementB = new Vertice(new SFML.System.Vector2f(mouse.X, mouse.Y));
      placementB.SetEnabled(false);
      placementEdge = new Edge(placementA, placementB);
      placementEdge.SetEnabled(false);
      window.Controls.Add(placementEdge);
      window.Controls.Add(placementA);
      window.Controls.Add(placementB);
   }
   else inPlacement = false;
}
private void WindowOnMouseMove(object sender, SFML.Window.MouseMoveEventArgs e) {
   if (inPlacement) {
      SFML.System.Vector2i mouse = SFML.Window.Mouse.GetPosition(window.Real);
      placementB.SetPosition(new SFML.System.Vector2f(mouse.X, mouse.Y));
      placementEdge.SetVerticeB(placementB);
   }
}
« Last Edit: March 25, 2016, 04:50:35 pm by globalenemy »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Quote
I know it could be that just my math is wrong
It is totally wrong ;)

This should work better:
public static double Distance(Vertice _a, Vertice _b) {
   return Math.Sqrt(Math.Pow((_a.X - _b.X), 2) + Math.Pow((_a.Y - _b.Y), 2));
}
public static double Angle(Vertice _a, Vertice _b) {
   double radians = Math.Atan2(_b.Y - _a.Y, _b.X - _a.X);
   return  radians * 180 / Math.PI;
}

And english is not my mother tongue, but I think "one vertice" is wrong; it's "one vertex, multiple vertices".
Laurent Gomila - SFML developer

globalenemy

  • Newbie
  • *
  • Posts: 10
    • View Profile
narf :\

thank you sir, now the edge is drawn and moved correct.
« Last Edit: March 25, 2016, 06:23:14 pm by globalenemy »