class MMnormal {

    // between 0 and 2*pi
    private double angle, cosa, sina;
    private double weight;
    // the x y components
    public float x, y; 

    // constructor from two points
    MMnormal (MMpoint b, MMpoint a) {
	x = - b.y + a.y;
	y = - a.x + b.x;
	angle = Math.atan2(y,x);
	if (angle < 0) angle += Math.PI*2;
//	angle = 2*Math.PI - angle;
	weight = Math.sqrt (x*x+y*y);
//	cosa = x/weight;
//	sina = y/weight;
	cosa = Math.cos(angle);
	sina = Math.sin(angle);
    }

    MMnormal (float x, float y, double weight, double angle, double cosa, double sina) {
	this.x = x;
	this.y = y;
	this.weight = weight;
	this.angle = angle;
	this.cosa = cosa;
	this.sina = sina;
    }

  MMnormal (MMnormal v) {
	this.x = v.x;
	this.y = v.y;
	this.weight = v.getWeight();
	this.angle = v.getAngle();
	this.cosa = v.getCosa();
	this.sina = v.getSina();
    }

    // mutator from two points
    void set (MMpoint a, MMpoint b) {
	x = - b.y + a.y;
	y = - a.x + b.x;
	angle = Math.atan2(y,x);
	if (angle < 0) angle += Math.PI*2;
//	angle = 2*Math.PI - angle;
	weight = Math.sqrt (x*x+y*y);
	cosa = Math.cos(angle);
	sina = Math.sin(angle);
    }

    public double getCosa () {
	return cosa;
    }
    
    public double getSina () {
	return sina;
    }

    public double getAngle () {
	return angle;
    }

    public double getWeight () {
        return weight;
    }

    public void scaleBy (double scaleFactor) {
	x *= scaleFactor;
	y *= scaleFactor;
	if (scaleFactor >= 0) {
	    weight *= scaleFactor;
	} else {
	    weight *= -scaleFactor;
	    if (angle>Math.PI) angle -= Math.PI; else angle += Math.PI;
	    cosa = -cosa;
	    sina = -sina;
	}
    }

    public MMnormal multBy (double scaleFactor) {
//	System.out.println("Scaling by "+Float.toString(scaleFactor));
	if (scaleFactor>=0) 
	    return(new MMnormal((float) (x*scaleFactor), (float) (y*scaleFactor), weight*scaleFactor, angle, cosa, sina));
	else
	    return(new MMnormal((float) (x*scaleFactor), (float) (y*scaleFactor), -weight*scaleFactor, angle>Math.PI?angle-Math.PI:angle+Math.PI, -cosa, -sina));
//	return(new MMnormal(new MMpoint(y * scaleFactor, -x * scaleFactor), new MMpoint (0, 0)));
    }

    public String toString() {
	return x+", "+y+" ,"+weight+", "+angle+", "+cosa+", "+sina;
    }
}
