0

基本的なモデル エディターを作成しようとしていますが、atan2 を理解していないか、予測不可能で苛立たしい結果が返されるため、使用するのに適切なソリューションではありません。このサイトの別のスレッドから借用したコードを少し使用して、2 点間の角度を取得しましたが、問題は、それが望んでいることを実行しておらず、正しい場所に回転していないことです。これは、モデルを設計し、レンダリングしてドラッグするクラスです。

import java.awt.*;
import java.awt.event.*;
import java.util.*;

import javax.swing.*;

public class ModelDesigner extends JPanel implements MouseListener, MouseMotionListener{
Skeleton CurrentSkeleton = new Skeleton();
ArrayList<Rectangle> ClickableJointPoints = new ArrayList<Rectangle>();
Joint SelectionJoint = null;

boolean Dragging = false;
Point ClickPoint = new Point(0, 0);

public ModelDesigner(){
    setBackground(Color.white);
    addMouseListener(this);
    addMouseMotionListener(this);
}

public void paintComponent(Graphics g){
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D) g.create();
    RenderSkeleton(g2, CurrentSkeleton);
}

void RenderSkeleton(Graphics2D g2, Skeleton e){
    for (Joint j : e.ChildJoints){
        RenderJoint(g2, j, getWidth() / 2, 10, 0);
    }
}

void RenderJoint(Graphics2D g2, Joint j, int ParentX, int ParentY, double r){
    g2.setColor(Color.black);
    Point p = getEndPointOfRotatedLine(j.Rotation + r, j.X, j.Y, j.Length);
    g2.drawLine(ParentX + j.X, ParentY + j.Y, ParentX + p.x, ParentY + p.y);
    g2.setColor(Color.red);
    g2.fillOval(ParentX + p.x - 3, ParentY + p.y - 3, 6, 6);
    if (j.HasChildren){
        for (Joint j2 : j.ChildJoints){
            RenderJoint(g2, j2, ParentX + p.x, ParentY + p.y, j.Rotation);
        }
    }
}

public static Point getEndPointOfRotatedLine(double angle, int x, int y, int length){
    Point p = new Point();
    p.x = (int) (x + length * Math.cos(angle));
    p.y = (int) (y + length * Math.sin(angle));
    return p;
}

@Override
public void mouseDragged(MouseEvent e) {
    Rectangle Click = new Rectangle(e.getX(), e.getY(), 1, 1);
    if (Dragging){
        SelectionJoint.Rotation = getAngle(ClickPoint, new Point(Click.x, Click.y));
        repaint();
    }
}

public double getAngle(Point orig, Point target) {
    double angle = (double) (Math.atan2(target.y - orig.y, target.x - orig.x));

    if(angle < 0){
        angle += 360;
    }

    return angle;
}

@Override
public void mouseMoved(MouseEvent arg0) {

}

@Override
public void mouseClicked(MouseEvent e) {

}

@Override
public void mouseEntered(MouseEvent e) {

}

@Override
public void mouseExited(MouseEvent e) {

}

@Override
public void mousePressed(MouseEvent e) {
    Rectangle Click = new Rectangle(e.getX(), e.getY(), 1, 1);
    /*
     *  Point p = getEndPointOfRotatedLine(j.Rotation, j.X, j.Y, j.Length);
     *  ClickableJointPoints.add(new Rectangle(p.x - 3, p.y - 3, 6, 6));
     */
    for (Joint j : CurrentSkeleton.ChildJoints){
        Point p = getEndPointOfRotatedLine(j.Rotation, j.X, j.Y , j.Length);
        //this.getGraphics().drawRect(p.x - 3 + (getWidth() / 2), p.y - 3 + 10, 6, 6);
        if (new Rectangle(p.x - 3 + getWidth() / 2, p.y - 3 + 10, 6, 6).intersects(Click)){
            System.out.println("intersection");
            SelectionJoint = j;
            Dragging = true;
            ClickPoint = p;
            return;
        }else{
            if (j.HasChildren){
                for (Joint j2 : j.ChildJoints){
                    if (getIntersectionOfRectAndJoints(Click, j2, j.X + p.x, j.Y + p.y, j.Rotation)){
                        return;
                    }
                }
            }
        }
    }

}

public boolean getIntersectionOfRectAndJoints(Rectangle r, Joint j, int parentX, int parentY, double rotation){
    Point p = getEndPointOfRotatedLine(j.Rotation + rotation, j.X, j.Y, j.Length);
    this.getGraphics().drawRect(parentX + p.x - 3 + (getWidth() / 2), parentY + p.y - 3 + 10, 6, 6);
    if (new Rectangle(parentX + p.x - 3 + getWidth() / 2, parentY + p.y - 3 + 10, 6, 6).intersects(r)){
        System.out.println("intersection");
        SelectionJoint = j;
        Dragging = true;
        ClickPoint = p;
        return true;
    }else{
        if (j.HasChildren){
            for (Joint j2 : j.ChildJoints){
                if (getIntersectionOfRectAndJoints(r, j2, parentX + j.X + p.x, parentY + j.Y + p.y, j.Rotation)){
                    return true;
                }
            }
        }
    }
    return false;
}

@Override
public void mouseReleased(MouseEvent e) {
    Dragging = false;
}
}

スケルトン クラスのコードは次のとおりです (基本モデルを作成するコンストラクターが付属しています)。

import java.util.ArrayList;

public class Skeleton {
ArrayList<Joint> ChildJoints = new ArrayList<Joint>();

/* 
 * The constructor just adds a fancy default skeleton, you should be able to add
 * and remove limbs, as well as change lengths eventually.
 */
public Skeleton(){
    //add the primary parent joint
    Joint HeadJoint = new Joint();
    HeadJoint.Length = 10;
    HeadJoint.Rotation = Math.toRadians(90);
    Joint Spine = new Joint();
    Spine.Length = 100;
    Spine.Rotation = Math.toRadians(0);
    Joint leftArm = new Joint();
    leftArm.Length = 50;
    leftArm.Rotation = Math.toRadians(45);
    Joint rightArm = new Joint();
    rightArm.Length = 50;
    rightArm.Rotation = Math.toRadians(315);
    Joint leftLeg = new Joint();
    leftLeg.Length = 60;
    leftLeg.Rotation = Math.toRadians(112);
    Joint rightLeg = new Joint();
    rightLeg.Length = 60;
    rightLeg.Rotation = Math.toRadians(68);
    Joint bottomLeftLeg = new Joint();
    bottomLeftLeg.Length = 35;
    bottomLeftLeg.Rotation = Math.toRadians(-10);
    Joint bottomRightLeg = new Joint();
    bottomRightLeg.Length = 35;
    bottomRightLeg.Rotation = Math.toRadians(10);
    ChildJoints.add(HeadJoint);
    HeadJoint.AddChild(Spine);
    HeadJoint.AddChild(leftArm);
    HeadJoint.AddChild(rightArm);
    Spine.AddChild(leftLeg);
    Spine.AddChild(rightLeg);
    leftLeg.AddChild(bottomLeftLeg);
    rightLeg.AddChild(bottomRightLeg);
}

public void MoveSkeleton(int newX, int newY){
    for (Joint j : ChildJoints){
        j.MoveJoint(newX, newY);
    }
}

}

Joint クラスのコードは次のとおりです。

import java.util.ArrayList;

public class Joint {
ArrayList<Joint> ChildJoints = new ArrayList<Joint>();

int Length = 0;
double Rotation = 0.0;

boolean HasChildren = false;

int X;
int Y;

String JointName = "unknown joint";

public void MoveJoint(int newX, int newY){
    X = newX;
    Y = newY;
    for (Joint j : ChildJoints){
        if (j.HasChildren){
            j.MoveJoint(newX, newY);
        }else{
            j.X = newX;
            j.Y = newY;
        }
    }
}

public void AddChild(Joint j){
    ChildJoints.add(j);
    HasChildren = true;
}

public void RemoveChild(int v){
    if (ChildJoints.size() == 0){
        HasChildren = false;
    }
}

}

すべてが実装されているわけではないため、コードはまだ少し乱雑ですが、少しいらいらしています。基本的に、角度が間違った場所に行く原因となっています。誰かが私の問題を理解しているなら、手を貸してください。ありがとうございました。

4

1 に答える 1

0

私は問題をある程度解決しました。親ジョイントの x と y の位置や実際のレンダリング座標など、ClickPoint を初期化するときに正しい座標を追加するのを忘れていました。助けてくれてありがとう、それは私のばかげた間違いでした。

于 2013-08-31T03:00:53.897 に答える