9 votos

Dada una circunferencia de radio r, y dos puntos ('X' y 'Z') sobre dicha circunferencia, ¿puede construirse algún arco de circunferencia "XYZ" de longitud r?

Soy estrictamente un aficionado, no un matemático profesional ni nada parecido.

Esta pregunta se me ocurrió al considerar el hecho de que un ángulo de 1 radián centrado en el centro de un círculo producirá un arco de circunferencia en el círculo de la misma longitud que el radio del círculo, mientras que dos segmentos (AB y BC) de igual longitud que se cruzan a 60 grados definirán, por supuesto, un tercer segmento de igual longitud (entre A y C).


Para elaborar:

  1. Definir una circunferencia C con punto central O y radio 'r'.
  2. Define dos puntos, X y Z, en la circunferencia C.
  3. Define las líneas OX y OZ.
  4. Define el ángulo XOZ.
  5. Definir la recta OA bisectriz de XOZ.
  6. Definir algún punto Y en OA tal que el arco de circunferencia XYZ sea de longitud r.

El punto 6, por supuesto, es el que no sé cómo hacer. Se me ha ocurrido que este problema está, por supuesto, restringido a casos en los que el ángulo XOZ es de menos de 60 grados (ya que a 60 grados, XYZ se convierte en un segmento de recta, y por encima de 60 grados, no puede existir ningún arco XYZ de longitud <= r.

También se me ha ocurrido que este problema también podría resolverse definiendo algún punto P sobre OA tal que exista una circunferencia D con punto central P y que pase por X (y Z), donde la longitud del arco XZ sobre la circunferencia D sea r, pero tampoco tengo ni idea de cómo hacerlo.

Diagrama

enter image description here

EDIT: Una cuestión relacionada de interés sería definir la función que describe la longitud de la línea OY relativa a la longitud de OX u OZ (es decir: 'r'), y el ángulo de XOZ. Naturalmente, habría dos valores válidos de OY, como indica @RossMillikan, uno para Y dentro del círculo y otro para Y fuera del círculo.

0 votos

El mundo necesita "aficionados" como tú porque mucha gente se enorgullece de odiar las matemáticas.

0 votos

@Piquito bueno, yo soy desarrollador de software. Es un campo relacionado, en el sentido de que ambos se basan en el pensamiento estrictamente lógico.

0 votos

Un trabajo interesante. Conozco escritores y artistas a los que les encantan las matemáticas, pero a la mayoría no. Por desgracia, hay que decirlo, algunos de los que dicen ser amantes de las matemáticas son en realidad unos esnobs.

2voto

Shabaz Puntos 403

Punto $Y$ existirá. Habrá dos puntos que cumplan el requisito, uno a cada lado de $XZ$ . Puedes demostrarlo utilizando el teorema del valor intermedio. El segmento $XZ$ es demasiado corto y el arco con $Y$ lejos será demasiado largo, así que hay un punto intermedio que es justo el adecuado. Estoy seguro de que en general no se podrá construir con compás y regla, pero no conozco una manera fácil de demostrarlo.

2voto

Wizzard Puntos 2126

Desde luego, no es una respuesta aceptable. Pero quizá sea una contribución útil. Acabo de hackear un pequeño programa donde se puede arrastrar alrededor de los puntos x / z, y se imprime parte de la información pertinente.

En particular, imprime el ángulo entre OX y OZ, y la longitud relativa de la línea OY (referida al radio).

enter image description here

Como ya has observado, la solución sólo puede existir para un ángulo que no sea mayor de 60°. (Para 60°, el resultado será simplemente el círculo original). En este caso, la distancia de Y a O será 1,0 (¡respecto al radio!).

En inferior El límite para el ángulo parece ser de unos 37°, y la distancia relativa de Y a O será entonces de 1,26 aproximadamente. Pero, por supuesto, este cálculo sólo da un áspero ¡aproximación!

La implementación está aquí, en Java. Debería ser independiente, y se puede compilar e iniciar directamente en cualquier IDE.

Pero nota : La aplicación es realmente crudo, así que tómatelo con humor. En particular, busca por "fuerza bruta" la distancia de Y a la que la longitud de arco resultante será aproximadamente igual al radio. Esto podría o debería mejorarse en muchos formas, por ejemplo haciendo una búsqueda binaria, y/o buscando ambos soluciones que se supone que existen en cada punto.

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class CircumcircleTest
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }

    private static void createAndShowGui()
    {
        JFrame frame = new JFrame();
        frame.getContentPane().add(new CircumcircleTestPanel());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(1200,800);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

class CircumcircleTestPanel extends JPanel
    implements MouseListener, MouseMotionListener
{

    private Point2D center;
    private double radius = 200;

    private Point2D x;
    private Point2D z;

    private Point2D draggedPoint = null;
    private List<Point2D> points;

    CircumcircleTestPanel()
    {
        super(null);

        center = new Point2D.Double(300, 300);
        x = new Point2D.Double(center.getX() + radius, center.getY() - radius);
        z = new Point2D.Double(center.getX() + radius, center.getY() + radius);
        validatePoints();

        points = new ArrayList<Point2D>();
        points.add(x);
        points.add(z);

        addMouseListener(this);
        addMouseMotionListener(this);
    }

    @Override
    protected void paintComponent(Graphics gr)
    {
        super.paintComponent(gr);
        Graphics2D g = (Graphics2D)gr;
        g.setRenderingHint(
            RenderingHints.KEY_ANTIALIASING,  
            RenderingHints.VALUE_ANTIALIAS_ON);
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, getWidth(), getHeight());

        g.setColor(Color.GRAY);
        drawCircle(g, new Circle(center, radius));

        g.setColor(Color.BLUE);
        drawPoint(g, center, "O");
        drawPoint(g, x, "X");
        drawPoint(g, z, "Z");

        double angleXZ = angle(center, x, center, z);

        g.setColor(Color.BLACK);
        drawLine(g, center, x);
        drawLine(g, center, z);

        g.setColor(Color.GREEN);
        Line2D bisector = computeBisector(center, x, z);
        g.draw(bisector);

        double arcLength = Double.NaN;
        double lengthRelativeToRadius = Double.NaN;

        Point2D y = computeY(bisector);
        if (y != null)
        {
            g.setColor(Color.RED);
            drawPoint(g, y, "Y");

            g.setColor(Color.GRAY);
            Circle c = computeCircumcircle(
                x.getX(), x.getY(),
                y.getX(), y.getY(),
                z.getX(), z.getY(), null);
            drawCircle(g, c);

            arcLength = computeArcLength(c.getCenter(), x, z);
            double distanceY = center.distance(y);
            lengthRelativeToRadius = distanceY / radius;
        }

        g.setColor(Color.BLACK);
        int tx = 10;
        int ty = 20;
        g.drawString("angleXZ: "+Math.toDegrees(angleXZ), tx, ty+=20);
        g.drawString("arcLength: "+arcLength, tx, ty+=20);
        g.drawString("lengthRelativeToRadius: "+lengthRelativeToRadius, 
            tx, ty+=20);

    }

    private Point2D computeY(Line2D bisector)
    {
        double minDeviation = Double.POSITIVE_INFINITY;
        Point2D closestY = null;
        double minDistanceToCenter = Double.POSITIVE_INFINITY;
        int n = 10000;
        for (int i=n; i<n+n; i++)
        {
            double alpha = (double)i / n;

            Point2D y = new Point2D.Double(bisector.getX2(), bisector.getY2());
            double distance = alpha * radius;
            validateDistance(center, y, distance);

            Circle c = computeCircumcircle(
                x.getX(), x.getY(),
                y.getX(), y.getY(),
                z.getX(), z.getY(), null);

            double arcLength = computeArcLength(c.getCenter(), x, z);
            double deviation = Math.abs(arcLength - radius);
            if (deviation < minDeviation && deviation < 0.1)
            {
                double distanceToCenter = center.distance(y);
                if (distance < minDistanceToCenter)
                {
                    minDistanceToCenter = distanceToCenter;
                    minDeviation = deviation;
                    closestY = y;
                }
            }
        }
        return closestY;
    }

    private static double computeArcLength(Point2D c, Point2D a, Point2D b)
    {
        // Based on https://math.stackexchange.com/a/830630/133498
        double d = a.distance(b);
        double r = c.distance(a);
        double theta = Math.acos(1 - ((d * d) / (2 * r * r)));
        double length = r * theta;
        return length;
    }

    private static Line2D computeBisector(Point2D c, Point2D p0, Point2D p1)
    {
        Line2D line0 = new Line2D.Double(c, p0);
        Line2D line1 = new Line2D.Double(c, p1);
        double angleRad = angle(line0, line1);
        return rotate(-angleRad * 0.5, line1, null);
    }

    static void drawPoints(Graphics2D g, List<Point2D> points)
    {
        for (Point2D point : points)
        {
            drawPoint(g, point, "x");
        }
    }

    private static void drawPoint(Graphics2D g, Point2D point, String label)
    {
        double r = 3;
        double x = point.getX();
        double y = point.getY();
        g.fill(new Ellipse2D.Double(x-r, y-r, r+r, r+r));
        g.drawString(label, (int)(x+10), (int)(y+10));
    }

    private static void drawLine(Graphics2D g, Point2D p0, Point2D p1)
    {
        g.draw(new Line2D.Double(p0,p1));
    }

    private static void drawCircle(Graphics2D g, Circle c)
    {
        g.draw(new Ellipse2D.Double(
            c.getCenter().getX()-c.getRadius(),
            c.getCenter().getY()-c.getRadius(),
            c.getRadius()+c.getRadius(),
            c.getRadius()+c.getRadius()));
    }

    private void validatePoints()
    {
        validateDistance(center, x, radius);
        validateDistance(center, z, radius);
    }

    private static void validateDistance(Point2D p0, Point2D p1, double d)
    {
        double dx = p1.getX() - p0.getX();
        double dy = p1.getY() - p0.getY();
        double distance = Math.sqrt(dx * dx + dy * dy);
        dx /= distance;
        dy /= distance;
        p1.setLocation(p0.getX() + d * dx, p0.getY() + d * dy);
    }

    @Override
    public void mouseDragged(MouseEvent e)
    {
        if (draggedPoint != null)
        {
            draggedPoint.setLocation(e.getPoint());
            validatePoints();
            repaint();
        }
    }

    @Override
    public void mouseMoved(MouseEvent e)
    {
    }

    @Override
    public void mouseClicked(MouseEvent e)
    {
    }

    @Override
    public void mousePressed(MouseEvent e)
    {
        draggedPoint = null;
        double thresholdSquared = 10*10;
        double minDs = Double.MAX_VALUE;
        for (Point2D point : points)
        {
            double ds = point.distanceSq(e.getPoint());
            if (ds < thresholdSquared && ds < minDs)
            {
                minDs = ds;
                draggedPoint = point;
            }
        }
    }

    @Override
    public void mouseReleased(MouseEvent e)
    {
        draggedPoint = null;
    }

    @Override
    public void mouseEntered(MouseEvent e)
    {
    }

    @Override
    public void mouseExited(MouseEvent e)
    {
    }

    static Circle computeCircumcircle(
        double x0, double y0, 
        double x1, double y1, 
        double x2, double y2,
        Circle circle)
    {
        // As described on http://mathworld.wolfram.com/Circumcircle.html
        double a = 
            x0 * (y1 - y2) - 
            x1 * (y0 - y2) + 
            x2 * (y0 - y1);
        double m00 = x0 * x0 + y0 * y0;
        double m10 = x1 * x1 + y1 * y1;
        double m20 = x2 * x2 + y2 * y2;
        double bx = 
            -(m00 * (y1 - y2) - 
              m10 * (y0 - y2) + 
              m20 * (y0 - y1));
        double by = 
              m00 * (x1 - x2) - 
              m10 * (x0 - x2) + 
              m20 * (x0 - x1);
        double c = 
            -(m00 * (y2 * x1 - x2 * y1) 
            - m10 * (y2 * x0 - x2 * y0) +
              m20 * (y1 * x0 - x1 * y0));
        double centerX = -bx * 0.5 / a;
        double centerY = -by * 0.5 / a;
        double radius =
            Math.sqrt(bx * bx + by * by - 4 * a * c) * 0.5 / Math.abs(a);
        if (circle == null)
        {
            return new Circle(new Point2D.Double(centerX, centerY), radius);
        }
        circle.setCenter(centerX, centerY);
        circle.setRadius(radius);
        return circle;
    }

    static class Circle
    {
        private final Point2D center;
        private double radius;

        Circle()
        {
            this.center = new Point2D.Double();
            this.radius = 0.0;
        }

        Circle(Point2D center, double radius)
        {
            this.center = center;
            this.radius = radius;
        }

        Point2D getCenter()
        {
            return center;
        }
        double getX()
        {
            return center.getX();
        }
        double getY()
        {
            return center.getY();
        }
        void setCenter(double x, double y)
        {
            center.setLocation(x, y);
        }
        double getRadius()
        {
            return radius;
        }
        void setRadius(double radius)
        {
            this.radius = radius;
        }
        boolean contains(Point2D p)
        {
            return contains(p.getX(), p.getY());
        }
        boolean contains(double x, double y)
        {
            if (Double.isInfinite(radius))
            {
                return true;
            }
            double dx = center.getX() - x;
            double dy = center.getY() - y;
            return dx * dx + dy * dy <= radius * radius;
        }

        @Override
        public String toString()
        {
            return "Circle[("+getX()+","+getY()+"),radius="+radius+"]";
        }

    }

    private static Line2D rotate(
        double angleRad, Line2D lineSrc, Line2D lineDst)
    {
        double x0 = lineSrc.getX1();
        double y0 = lineSrc.getY1();
        double x1 = lineSrc.getX2();
        double y1 = lineSrc.getY2();
        double dx = x1 - x0;
        double dy = y1 - y0;
        double sa = Math.sin(angleRad);
        double ca = Math.cos(angleRad);
        double nx = ca * dx - sa * dy;
        double ny = sa * dx + ca * dy;
        if (lineDst == null)
        {
            lineDst = new Line2D.Double();
        }
        lineDst.setLine(x0, y0, x0+nx, y0+ny);
        return lineDst;
    }    

    private static double angle(Line2D line0, Line2D line1)
    {
        return normalizeAngle(angleToX(line1) - angleToX(line0));
    }

    private static double angle(
        Point2D s0, Point2D e0, Point2D s1, Point2D e1)
    {
        return normalizeAngle(angleToX(s1, e1) - angleToX(s0, e0));
    }

    private static double angleToX(Line2D line)
    {
        return angleToX(
            line.getX1(), line.getY1(), 
            line.getX2(), line.getY2());
    }

    private static double angleToX(
        Point2D p0, Point2D p1)
    {
        return angleToX(
            p0.getX(), p0.getY(), 
            p1.getX(), p1.getY());
    }

    private static double angleToX(
        double x0, double y0, double x1, double y1)
    {
        double dx = x1 - x0;
        double dy = y1 - y0;
        double angleRad = Math.atan2(dy, dx); 
        return angleRad;
    }

    static double normalizeAngle(double angle)
    {
        return (angle + Math.PI + Math.PI) % (Math.PI + Math.PI);        
    }

}

0 votos

Bueno, como ya he mencionado, también soy desarrollador de software, así que me encanta algo a lo que pueda hincarle el diente desde un punto de vista profesional. Sin embargo, me di cuenta de un problema de inmediato en su descripción, por lo menos. El resultado es el círculo original a 1 radián (~57,29 grados), no a 60 grados. Esto parece coincidir con tu animación. Por el contrario, a 60 grados, el círculo resultante no existe, ya que la línea recta entre X y Z tiene la longitud necesaria (XOZ es un triángulo equilátero cuando el ángulo de XOZ es de 60 grados).

0 votos

De nuevo, se trata de aproximaciones, y siempre hay problemas de estabilidad. No puedo enfatizar lo suficiente que este fue un hack rápido, con el fin de "jugar" y observar el comportamiento un poco. Hay algunas constantes, como radius=200 , n=1000 , deviation<0.1 . Jugueteando con esto para radius=10 , n=10000 , deviation<1.0 hará que el resultado se imprima a ~60°. (Si se desea, podría intentar hacer los cálculos más robustos, pero tendría que ver cómo asignar algo de tiempo para ello...).

2voto

Ataulfo Puntos 3108

Aquí una forma de resolver tu problema: en la figura adjunta puedes calcular el ángulo theta en el triángulo rectángulo $\triangle{XX'O}$ que es la mitad del triángulo isósceles $\triangle{XOY}$ con ángulo $\angle{XOY}=2\alpha\lt 60^{\circ}$ .

Cada valor del segmento $\overline{OA}=a$ donde $0\lt \overline{OA}\lt R\cos(\alpha)$ determina tanto el ángulo $\theta$ y el "pequeño" radio $r$ . Usted tiene $$\begin{cases}r=\sqrt{R^2+a^2-2aR\cos(\alpha)}\\\theta=\arcsin\left(\dfrac{R\sin(\alpha)}{r}\right)\end{cases}\qquad(*)$$

Finalmente su ecuación es $$2r\theta=R$$ es decir $$2\sqrt{R^2+a^2-2aR\cos(\alpha)}\arcsin\left(\dfrac{R\sin(\alpha)}{r}\right)=R\qquad(**)$$ Debe poner $(**)$ el valor de $r$ dado en $(*)$ Por supuesto. Finalmente tienes una ecuación en una variable $a$ desde $R$ y $\alpha$ son datos del problema. enter image description here

1voto

Emilio Novati Puntos 15832

COMO señaló Ross Millikan el punto buscado.

Puedo sugerir un camino para encontrarla. Yo uso la figura con diferentes nombres:

enter image description here

donde sabemos que:

$\overline{AC}=\overline{AB}=r$

$\angle CAE=\angle CAD=\gamma$

y buscamos:

$\angle CED=\theta $

$\angle ACE=\varphi$

de modo que tenemos $$ \theta=\gamma+ \varphi \qquad (1) $$

con: $\overline{CE}=x\quad$ y $\quad \overline{AE}=y$

utilizando la baja de los cosenos para el triángulo $ACE$ hemos $$ y^2=r^2+x^2-2rx\cos \varphi \qquad (2) $$ y, utilizando los triángulos $ACD$$CED$: $$ r^2+(y+x)^2-2r(y+x)\cos \gamma = 2x^2-2x^2\cos \theta \qquad (3) $$

y, con la ecuación que da el arco $CDB=r$: $$ 2x\theta=r \qquad (4) $$ tenemos cuatro ecuaciones para las cuatro incógnitas.

El sistema no es sencillo de resolver, y tal vez que se puede simplificar con una opción diferente de las incógnitas.

0voto

Cybolic Puntos 177

Prefacio. Me tomó algo de tiempo para entender la pregunta, así que perdón por mi inicial de la idiotez. Me parece que es algo interesante. Aquí está un informe de lo que hice.

Consulte la figura en la OP. Queremos que la arc $XYZ$ cuya longitud es igual a $r$. Como OP, dijo, no tiene sentido buscar esto para $X\hat O Z=\theta\ge π/3$. Ahora es fácil ver que es suficiente para encontrar el radio $s$ de la buscó el arco con una longitud de $x$, para una vez que sabemos esto podemos encontrar siempre el centro de las limitaciones que el arco debe pasar a través de $X$ $Z$ y centrada en algún lugar de la línea de $OA$. Desde siempre tenemos dos arcos (formando un círculo completo), se elige la más pequeña, y es el único cuya longitud denotamos por a $x$. Los posibles radios $s$ de estos arcos deben satisfacer $s\ge c$ donde $c$ es la mitad de la cuerda $XZ$. Ahora, para cada una de las $s$ siempre tenemos dos arcos (contando multiplicidades), pero consideramos que ellos sean uno (es decir, consideramos que la congruencia de la clase de los arcos en lugar de individuos, con exactamente dos por clase), ya que sólo estamos interesados en sus longitudes, que debe ser igual, ya que son congruentes. Además, buscamos tal $s$ hacer $x=1$ fijos $\theta\in(0,π/3)$.

Puesto que para cada una de las $r\ge c$, tenemos uno y sólo un valor de $x$, podemos formar una función de $x(s)$ y simplemente investigar la $s$ que solucionar $x=1$. Esto disuelve el problema para algunos positivos $\theta<π/3$.

Considerando la figura podemos ver de inmediato que $x$ debe cumplir con lo siguiente:

  1. La función de $x(s)$ es continua.

  2. Disminuye estrictamente con el aumento de la $r$.

  3. En $s=c=r\sin{\theta/2}$, el mínimo en el dominio, tenemos $x(c)=πc$.

  4. Al$s=r$, $x(r)=\theta$ siempre $\theta$ satisface las restricciones impuestas en ella.

  5. La gráfica de $x$ intercepta ambos ejes de la nada.

  6. Como $r\to\infty$, $x\to 2c$.

  7. En consecuencia (específicamente por 2 y 5), $x$ está acotada.

Ahora podemos imaginar, por $\theta=1$$r=1$, por ejemplo, que la gráfica de $x$ se ve como un segmento (es decir, de alrededor de $r=1/2$$\infty$) de la gráfica de $e^{-s}$ traducido hacia arriba.

A partir de ahora, vamos a tomar las $r=1$ ya que debemos tener una unidad. Si tenemos en cuenta el diagrama y hacer algunas construcciones sencillas, vamos a ver que $x=s\phi$ donde $\phi$ es el ángulo del arco que buscamos, subtendido en el centro $P$. Tenga en cuenta que $\phi$ disminuye de $π$ $0$con el aumento de la $r$. Para encontrar una relación entre el $s$ $\phi$ es fácil. Deje $P$ ser el centro de la arc $XYZ$, entonces consideramos el triángulo $PXQ$ donde $Q$ es el punto donde el acorde $XZ$ y la línea de $OA$ se cruzan. De esto podemos ver que $s\sin\phi/2=c=r\sin\theta/2=\sin\theta/2$. Sustituyendo en la anterior relación y haciendo un poco de reordenamiento da $$x(s)=2s\arcsin\left(\frac 1s \sin\frac \theta2\right)$$ for $s\ge\sin(\theta/2)$ and fixed $\theta$. Indeed if we choose $\theta=1$ and set $x=1$, we find the only solution to be $s=1$, as expected. For any fixed $\theta$, it is easy to see that there is exactly one solution since the constant function $1$ must intersect $x$ en la mayoría de los una vez, estando estrictamente decreciente.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X