discontinuedPackage jet_cad_floor_plan has been discontinued and replaced by jet_cad_2d_plan.

rotateTableCommand function

DraftCommand? rotateTableCommand(
  1. DraftDocument doc,
  2. Handle instance,
  3. int quarterTurns
)

The command that turns instance by quarterTurns × 90° (positive is counter-clockwise, on the world and on the screen alike) about its definition's base point, or null when instance is not a live instance of a live definition. One TransformNodeCommand in a Rotate compound.

The new linear part is exact: a quarter turn only swaps and negates the entries, and 0.0 is stored for −0.0, so four turns return it bit for bit. The translation keeps the base point's world position; it is exact for a table placed at integer coordinates and within rounding otherwise.

Implementation

DraftCommand? rotateTableCommand(
    DraftDocument doc, Handle instance, int quarterTurns) {
  final node = doc.tree[instance];
  if (node is! InstanceNode) return null;
  final definition = doc.tree.definition(node.definition);
  if (definition == null) return null;
  final t = node.transform;
  final bp = definition.basePoint;
  final worldX = t.a * bp.x + t.c * bp.y + t.e;
  final worldY = t.b * bp.x + t.d * bp.y + t.f;

  final q = ((quarterTurns % 4) + 4) % 4;
  // R(q · 90°) · L, written as swaps and negations.
  final (a, b, c, d) = switch (q) {
    0 => (t.a, t.b, t.c, t.d),
    1 => (-t.b, t.a, -t.d, t.c),
    2 => (-t.a, -t.b, -t.c, -t.d),
    _ => (t.b, -t.a, t.d, -t.c),
  };
  double clean(double v) => v == 0 ? 0.0 : v;
  final e = worldX - (a * bp.x + c * bp.y);
  final f = worldY - (b * bp.x + d * bp.y);
  return CompoundCommand([
    TransformNodeCommand(instance,
        Transform2(clean(a), clean(b), clean(c), clean(d), clean(e), clean(f))),
  ], label: 'Rotate');
}