SLVS_C_ANGLE with signed angles

Abierto
#1,670 1 comentario 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
4/5
Tiempo estimado
3-5 días
Aptitud para principiantes
25/100
Tipo de issue
Nueva funcionalidad
Claridad
Bastante claro
Estado de actividad
Estancado
Stack tecnológico
cpp

Línea de trabajo

Start by reading the constraint handling in constrainteq.cpp and locating where constraint types and the SLVS_C_* API constraints are defined. The issue proposes adding SIGNED_ANGLE and SLVS_C_SIGNED_ANGLE, with the shown signed-angle behavior; done means the new constraint is integrated and tested to distinguish positive from negative angles.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

This might be the wrong place to post this, but there is no discussion section.

For visual based modeling SLVS_C_ANGLE makes a lot of sense, where the angle between lines entityA and entityB is equal to valA, and it doesn't matter in what direction, CW or CCW. So it has two solutions.

For a code based CAD it makes more sense if you can specify what direction. I took SLVS_C_ANGLE and created a SLVS_C_SIGNED_ANGLE constraint. It respects the sign of vaIA, so there is only one solution. For example valA=10 produces a different solution from valA=-10. I thought I'd share it here in case someone else wants to do the same. I've tested it and seems to work.

In constrainteq.cpp:

        case Type::SIGNED_ANGLE: {
            EntityBase *a = SK.GetEntity(entityA);
            EntityBase *b = SK.GetEntity(entityB);
            ExprVector ae = a->VectorGetExprs();
            ExprVector be = b->VectorGetExprs();
            if(other) ae = ae.ScaledBy(Expr::From(-1));

            // Get cosine and sine of current oriented angle (in workplane)
            Expr *cos_expr = DirectionCosine(workplane, ae, be);
            Expr *sin_expr = DirectionSine(workplane, ae, be);

            // Target angle in radians (signed)
            Expr *target_rads = exA->Times(Expr::From(PI/180.0));
            Expr *target_cos  = target_rads->Cos();
            Expr *target_sin  = target_rads->Sin();

            // Residuals: enforce both cos and sin match -> pins direction
            Expr *res_cos = cos_expr->Minus(target_cos);
            Expr *res_sin = sin_expr->Minus(target_sin);

            // Gain adjustment near 0/180
            double cos_eval = fabs(cos_expr->Eval());
            double gain = (cos_eval > 0.99) ? 0.01 / (1.00001 - cos_eval) : 1.0;
            Expr *mult = Expr::From(gain);

            AddEq(l, res_cos->Times(mult), 0);
            AddEq(l, res_sin, 1);  // sin is already signed, no need for extra gain here

            return;
        }        

Helper function:

Expr *ConstraintBase::DirectionSine(hEntity wrkpl,
                                    ExprVector ae, ExprVector be)
{
    if (wrkpl == EntityBase::FREE_IN_3D) {
        return Expr::From(0.0);
    } else {
        // In workplane: project into u-v plane, compute signed 2D cross product
        EntityBase *w = SK.GetEntity(wrkpl);
        ExprVector u = w->Normal()->NormalExprsU();
        ExprVector v = w->Normal()->NormalExprsV();

        Expr *ua = u.Dot(ae);
        Expr *va = v.Dot(ae);
        Expr *ub = u.Dot(be);
        Expr *vb = v.Dot(be);

        Expr *cross2d = (va->Times(ub))->Minus(ua->Times(vb));

        Expr *maga = (ua->Square()->Plus(va->Square()))->Sqrt();
        Expr *magb = (ub->Square()->Plus(vb->Square()))->Sqrt();
        Expr *denom = maga->Times(magb);

        return cross2d->Div(denom);
    }
}

Then you also need to define SIGNED_ANGLE and SLVS_C_SIGNED_ANGLE in the appropriate places.

Lenguaje dominante
C++
Estrellas
4.2k
Forks
600
Merge medio
9 h 37 min
PR fusionados (30 d)
9

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de solvespace/solvespace

Todos los issues de solvespace/solvespace

Issues similares

Más issues de C++

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.