Di chuyển một hạt xung quanh một vòng xoắn ốc Archimedean với tốc độ không đổi


8

Tôi muốn di chuyển một hạt trong một vòng xoắn ốc với tốc độ không đổi. Lưu ý rằng đó không phải là tốc độ góc không đổi. Điều này tỏ ra khá khó khăn và tôi sẽ thực hiện theo phương pháp của mình cho đến nay.

Hình xoắn ốc trong câu hỏi là một hình xoắn ốc Archimedean cổ điển với phương trình cực r = ϑvà phương trình tham số x = t*cos(t), y = t*sin(t). Cái này trông như thế này:nhập mô tả hình ảnh ở đây

Tôi muốn di chuyển một hạt xung quanh xoắn ốc, thật ngây thơ, tôi chỉ có thể đưa ra vị trí hạt là giá trị của t, và tốc độ khi tăng t. Bằng cách đó, hạt di chuyển quanh vòng xoắn ốc với tốc độ góc không đổi. Tuy nhiên, điều này có nghĩa là càng đi ra khỏi trung tâm, tốc độ (không góc) của nó càng nhanh.

Vì vậy, thay vì tăng tốc độ của tôi trong t, tôi muốn tốc độ của tôi là tăng chiều dài cung. Lấy chiều dài vòng cung của hình xoắn ốc là thử thách đầu tiên, nhưng do thực tế là hình xoắn ốc Archimedean tôi đang sử dụng không quá điên rồ, chức năng độ dài hình cung nằm ở đâu a = 1. Điều này cho phép tôi chuyển đổi các giá trị theta thành độ dài cung, nhưng đó là điều ngược lại chính xác với những gì tôi cần. Vì vậy, tôi cần tìm ra nghịch đảo của hàm độ dài cung, và tại rào cản đó, Wolfram-Alpha đã làm tôi thất bại.

Vì vậy, có thể tìm thấy nghịch đảo của hàm độ dài cung? Hàm này là ánh xạ một đến một, nếu bạn loại trừ các giá trị âm của theta.

Cảm ơn,

Laurie


1
Tôi nghĩ bạn sẽ nhận được câu trả lời nhanh hơn về toán học tràn. Nó có liên quan đến GameDev.
giảm tốc

Điều này sẽ dễ dàng hơn nếu nó không phải là tham số - nó có phải vậy không?
CiscoIPPhone

Có phải hình xoắn ốc phải được Archimedean?
Kỹ sư

@Cisco Vâng, tôi đã đưa ra phương trình cực, và chúng có thể hoán đổi cho nhau khá nhiều
Blue Peppers

@Nick Có: P Logarit và / hoặc lituus không phải là thứ tôi muốn
Blue Peppers

Câu trả lời:


12

Hãy làm phức tạp vòng xoắn ốc của bạn:

p (t): = (cos (t) · f (t), tội lỗi (t) · f (t))

trong trường hợp của bạn f (t): = t, trong tôi f (t): = 1 (vì vậy tôi trả lại các biến chứng của mình bằng cách đơn giản hóa :)

Nếu bạn muốn đi ở một tốc độ nhất định trong vòng xoắn thoái hóa này (một vòng tròn), bạn phải biết vòng xoắn ốc của bạn dài bao nhiêu để bạn có thể nói bao nhiêu vòng mỗi giây để chắc chắn rằng điểm của bạn di chuyển với tốc độ mong muốn .

Bây giờ chúng ta biết rằng mỗi vòng hoàn chỉnh trong một vòng tròn là 2 · π · r dài: 2 · π · 1 trong trường hợp của chúng ta; nếu ω là tốc độ vòng quay (tính bằng vòng trên giây) thì tốc độ V sẽ là V = 2 · π · 1 · hoặc theo cách tổng quát hơn:

V = 2 · π · r ·

nếu r là bán kính chung; Điều này cho chúng ta biết rằng:

V / (2 · π · r) = ω

nếu r là hàm của t chúng ta có thể nói:

ω (t) = V / (2 · π · r (t))

trong trường hợp "phức tạp" của tôi, điều này có thể được viết lại như sau:

ω (t) = V / (2 · π · f (t))

trong trường hợp "đơn giản hóa" của bạn, câu trả lời là:

ω (t) = V / (2 · π · t)

Bạn biết tốc độ không đổi V mong muốn của bạn, bạn biết: 2, πt là biến của bạn: bạn biết tất cả mọi thứ và bạn đã sẵn sàng để đi!

xấp xỉ vòng tròn cho vùng lân cận vô hạn của xoắn ốc trong t

xấp xỉ đường tròn cho vùng lân cận cực tiểu của xoắn ốc trong t

[TUYÊN BỐ TỪ CHỐI]

Đây không phải là một điều trị toán học nghiêm ngặt: nó không tính đến sự đóng góp của vi phân của f và cũng không nói loại chức năng nào không thể được sử dụng.


Vì vậy, sử dụng phương trình cuối cùng bạn giải cho w (t) và sau đó đưa nó vào phương trình tham số ban đầu để có được vị trí của hạt, điều đó có đúng không?
CiscoIPPhone

Oh đây thực sự là một câu trả lời tuyệt vời. Và do sử dụng f (t) thay vì t, chúng ta có thể sửa đổi vòng xoắn ốc của mình với giải pháp này vẫn hoạt động. Cảm ơn rât nhiều.
Peppers xanh

@CiscoIPPhone w (t) là tốc độ quay, nó cho bạn biết bao nhiêu thêm vào t của bạn khi thời gian trôi qua, sau đó sử dụng t để có được vị trí.
FxIII

@Blue Peppers như tôi đã nói trong phần từ chối trách nhiệm là không đúng với mọi f (t), nó hoạt động nếu f (t) di chuyển chậm (và khác biệt)
FxIII

2

Nếu bạn không bận tâm đến một giả định khá chính xác khá nhanh, thì giải pháp đơn giản này hoạt động khá tốt:

theta = r = sqrt(2) . sqrt({time})

Đây là tham số trong thời gian, khá tiện dụng. Tuy nhiên, để có được điều này tôi cần phải giả định rằng chuyển động gần như là hình tròn - tức là. vận tốc tuyến tính tức thời tỷ lệ với bán kính nhân với vận tốc góc:

{velocity} ~= {radius} . d{theta} / d{time}

Để cho thấy rằng giải pháp hoạt động, cắm nó vào d{theta} / d{time}:

d{theta} / d{time} = d(sqrt(2).{time}^(1/2)) / d{time}
                   = (sqrt(2) / 2) . {time}^(-1/2))
                   = 1 / {theta}
                   = 1 / {radius}
=> {velocity} = {radius} / {radius} = 1, as required.

Tại {time}=1, nơi này đặt một điểm ở khoảng cách sqrt(2)từ điểm gốc. Sau này, phép tính gần đúng cải thiện đáng kể: sự phân tách (tuyến tính, không dọc theo đường dẫn) giữa các điểm tiếp theo là 1.13, 1.08, 1.06. Sau 100 điểm, khoảng cách nhỏ hơn 1,0023.


0

Trong khi tìm kiếm một giải pháp tính toán góc tương ứng với độ dài cung nhất định, tôi tình cờ thấy câu hỏi này và câu trả lời hiện tại. Thật không may, câu trả lời này cũng như bất kỳ tài nguyên nào khác mà tôi tìm thấy trên web có thể được sử dụng trực tiếp để thực hiện.

Rõ ràng, tính toán nghịch đảo của hàm độ dài cung (cũng được cung cấp trong câu hỏi) là rất khó. Nhưng một phép tính gần đúng của nghịch đảo này bằng Phương pháp lặp Newton là có thể. Sau đây là một lớp chủ yếu cung cấp hai phương thức:

  • computeArcLength(double alpha, double angleRad): Tính độ dài cung của một điểm trên Vòng xoắn ốc Archimedean trong đó alphakhoảng cách giữa các lần quay liên tiếp và angleRadlà góc tính theo radian
  • computeAngle(double alpha, double arcLength, double epsilon): Tính góc mà điểm cho độ dài cung đã cho nằm trên Vòng xoắn ốc Archimedean, trong đó alphakhoảng cách giữa các lần quay liên tiếp và epsilonlà ngưỡng xấp xỉ của Lặp lại Newton

Mã được triển khai ở đây trong Java, nhưng các phương thức cốt lõi này phải là ngôn ngữ không thể tin được:

import java.awt.geom.Point2D;

/**
 * A class for computations related to an Archimedean Spiral
 */
class ArchimedeanSpiral
{
    /**
     * Computes an approximation of the angle at which an Archimedean Spiral
     * with the given distance between successive turnings has the given 
     * arc length.<br>
     * <br>
     * Note that the result is computed using an approximation, and not
     * analytically. 
     * 
     * @param alpha The distance between successive turnings
     * @param arcLength The desired arc length
     * @param epsilon A value greater than 0 indicating the precision
     * of the approximation 
     * @return The angle at which the desired arc length is achieved
     * @throws IllegalArgumentException If the given arc length is negative
     * or the given epsilon is not positive
     */
    static double computeAngle(
        double alpha, double arcLength, double epsilon)
    {
        if (arcLength < 0)
        {
            throw new IllegalArgumentException(
                "Arc length may not be negative, but is "+arcLength);
        }
        if (epsilon <= 0)
        {
            throw new IllegalArgumentException(
                "Epsilon must be positive, but is "+epsilon);
        }
        double angleRad = Math.PI + Math.PI;
        while (true)
        {
            double d = computeArcLength(alpha, angleRad) - arcLength;
            if (Math.abs(d) <= epsilon)
            {
                return angleRad;
            }
            double da = alpha * Math.sqrt(angleRad * angleRad + 1);
            angleRad -= d / da;
        }
    }

    /**
     * Computes the arc length of an Archimedean Spiral with the given
     * parameters
     * 
     * @param alpha The distance between successive turnings
     * @param angleRad The angle, in radians
     * @return The arc length
     * @throws IllegalArgumentException If the given alpha is negative
     */
    static double computeArcLength(
        double alpha, double angleRad)
    {
        if (alpha < 0)
        {
            throw new IllegalArgumentException(
                "Alpha may not be negative, but is "+alpha);
        }
        double u = Math.sqrt(1 + angleRad * angleRad);
        double v = Math.log(angleRad + u);
        return 0.5 * alpha * (angleRad * u + v);
    }

    /**
     * Compute the point on the Archimedean Spiral for the given parameters.<br>
     * <br>
     * If the given result point is <code>null</code>, then a new point will
     * be created and returned.
     * 
     * @param alpha The distance between successive turnings
     * @param angleRad The angle, in radians
     * @param result The result point
     * @return The result point
     * @throws IllegalArgumentException If the given alpha is negative
     */
    static Point2D computePoint(
        double alpha, double angleRad, Point2D result)
    {
        if (alpha < 0)
        {
            throw new IllegalArgumentException(
                "Alpha may not be negative, but is "+alpha);
        }
        double distance = angleRad * alpha;
        double x = Math.sin(angleRad) * distance;
        double y = Math.cos(angleRad) * distance;
        if (result == null)
        {
            result = new Point2D.Double();
        }
        result.setLocation(x, y);
        return result;
    }

    /**
     * Private constructor to prevent instantiation
     */
    private ArchimedeanSpiral()
    {
        // Private constructor to prevent instantiation
    }
}

Một ví dụ về cách sử dụng mục tiêu này cho mục tiêu được mô tả trong câu hỏi được đưa ra trong đoạn trích này: Nó tạo ra một số điểm nhất định trên hình xoắn ốc, với khoảng cách (độ dài cung!) Mong muốn giữa các điểm:

import java.awt.geom.Point2D;
import java.util.Locale;

public class ArchimedeanSpiralExample
{
    public static void main(String[] args)
    {
        final int numPoints = 50;
        final double pointArcDistance = 0.1;
        final double alpha = 0.5;
        final double epsilon = 1e-5;

        double totalArcLength = 0.0;
        double previousAngleRad = 0.0; 
        for (int i=0; i<numPoints; i++)
        {
            double angleRad = 
                ArchimedeanSpiral.computeAngle(alpha, totalArcLength, epsilon);
            Point2D point = 
                ArchimedeanSpiral.computePoint(alpha, angleRad, null);
            totalArcLength += pointArcDistance;

            // Compute and print the arc lengths, for validation:
            double currentArcLength = 
                ArchimedeanSpiral.computeArcLength(alpha, angleRad);
            double previousArcLength = 
                ArchimedeanSpiral.computeArcLength(alpha, previousAngleRad);
            double arcDistance = (currentArcLength - previousArcLength);
            System.out.printf(Locale.ENGLISH,
                "Point (%6.2f, %6.2f  distance in arc "
                + "length from previous is %6.2f\n",
                point.getX(), point.getY(), arcDistance);

            previousAngleRad = angleRad;
        }
    }
}

Các thực tế chiều dài hồ quang khoảng cách các điểm tính toán được in, và người ta có thể thấy rằng họ đang có trong thực tế cách đều, với mong muốn khoảng cách chiều dài hồ quang.


0

Tôi cũng đang vật lộn với điều này.

Những gì tôi đang làm là giữ cho vận tốc không đổi và thay đổi hướng của vật thể.

Nếu tôi thực hiện để góc (tính bằng độ) bằng khoảng cách từ gốc tọa độ, nhân với một hằng số, tôi sẽ có được một vòng xoắn ốc hoàn hảo đẹp. hằng số lớn hơn có ít không gian hơn giữa các dòng. Vấn đề duy nhất là nếu tốc độ quá cao, thì nó sẽ nhảy theo dõi và rối tung lên. vì vậy xoắn ốc chặt hơn đòi hỏi một tốc độ chậm hơn để theo dõi đáng tin cậy.

direction = ((spiral_factor*(current_distance) mod 360);

Trong đó current_distance là bán kính được vẽ từ vị trí đến điểm sinh sản tính bằng pixel, được lấy bởi một hàm động cơ cung cấp cho tôi.

Điều gì đẩy tôi lên tường là nghịch đảo. đặt đối tượng ở BÊN NGOÀI và để nó theo dõi vòng xoắn ốc Archimedean. Di chuyển hạt theo cách ngược lại không hoạt động. mà chỉ xoay xoắn ốc 180 độ. đảo ngược hướng cho một chiều kim đồng hồ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.