Παρασκευή 6 Οκτωβρίου 2023

CleanCodeBadPerformance Test

 

"Clean" Code, Horrible Performance

"Clean" Code, Horrible Performance - YouTube




loaded 10000000 Shapes

copied to arrays 3332483 3332550 3334967 ?=? 10000000 : 6664966 ,6665100 ,3334967

6664966 , 6665100 , 3334967

TotalArea1=4.741709582246646E8 in millis: 252

TotalArea2=4.741709582246208E8 in millis: 30 ok....!!!!!!

lesson learned!!!!!

BUILD SUCCESSFUL (total time: 4 seconds)



-------------------------------



/*

 * To change this license header, choose License Headers in Project Properties.

 * To change this template file, choose Tools | Templates

 * and open the template in the editor.

 */

package testcleancode;


import java.util.Random;

import java.util.Vector;


/**

 *

 * @author dimitrak

 * https://www.youtube.com/watch?v=tD5NrevFtbU

 */

public class TestCleanCode {

    static Random r=new Random();

    static Vector<Sx> v=new Vector<>();

    static double rv[];

    static double tv[];

    static double cv[];

    static int lr=0,lt=0,lc=0;

    static int ir=0,it=0,ic=0;

    /**

     * @param args the command line arguments"Clean" Code, Horrible Performance

     */

    public static void main(String[] args) {

        // TODO code application logic here

        prepareVect();

        test1();

        test2();

        

    }

    static void prepareVect(){

        int sxCount=10000000;

        int i=0;

        while(i<sxCount){

            int type=r.nextInt(3);

            if(type>0){

                if(type>1){

                    v.add(new Cir());

                    ++lc;

                }

                else{

                    v.add(new Tri());

                    ++lt;

                }

            }

            else{

                v.add(new Rec());

                ++lr;

            }

            ++i;

        }

        System.out.println("loaded "+sxCount+" Shapes");

        

        rv=new double[2*lr];

        tv=new double[2*lt];

        cv=new double[lc];

        i=0;

        while(i<sxCount){

            Sx s=v.get(i);

            if(s instanceof Rec){

                Rec rec =(Rec)s;

                rv[ir]=rec.w;

                ++ir;

                rv[ir]=rec.h;

                ++ir;

            }

            else if(s instanceof Tri){

                Tri tri =(Tri)s;

                tv[it]=tri.w;

                ++it;

                tv[it]=tri.h;

                ++it;

            }

            else{

                Cir cir =(Cir)s;

                cv[ic]=cir.r;

                ++ic;

            }

            ++i;

        }

        System.out.println("copied to arrays "+lr+" "+lt+" "+lc+" ?=? "+(lc+lr+lt)+" : "+rv.length+" ,"+tv.length+" ,"+cv.length);

        System.out.println(ir+" , "+it+" , "+ic);

    }

    static void test2(){

        double totArea2=0;

        

        int i=0;

        double w,h;

        long t2s=System.currentTimeMillis();


        i=0;

        while(i<rv.length){

            w=rv[i];

            ++i;

            h=rv[i];

            ++i;

            totArea2+=w*h;

            //System.out.println("rec("+w+","+h+")="+(w*h));

        }

        i=0;

        while(i<tv.length){

            w=tv[i];

            ++i;

            h=tv[i];

            ++i;

            totArea2+=(w*h)/2.0;

        }

        i=0;

        while(i<cv.length){

            w=cv[i];

            ++i;

            h=w;

            totArea2+=Math.PI*w*h;

        }

        long t2e=System.currentTimeMillis();

        long t2=t2e-t2s;

        

        

        System.out.println("TotalArea2="+totArea2+" in millis: "+t2);

        

        

    }

    static void test1(){

        

        

        int i=0;

        int l=v.size();

        double totArea1=0;

        long t1s=System.currentTimeMillis();

        while(i<l){

            totArea1+=v.get(i).area();

            ++i;

        }

        long t1e=System.currentTimeMillis();

        long t1=t1e-t1s;

        System.out.println("TotalArea1="+totArea1+" in millis: "+t1);

        


        

    }

    

}



abstract class Sx{

    

    public abstract double area();

}


class Rec extends Sx{

    public Rec(){

        w=10*TestCleanCode.r.nextDouble();

        h=10*TestCleanCode.r.nextDouble();

    }

    double w,h;

    public double area(){

        //System.out.println("Rec("+w+","+h+")="+(w*h));

        return w*h;

    }

}

class Tri extends Sx{

    public Tri(){

        w=10*TestCleanCode.r.nextDouble();

        h=10*TestCleanCode.r.nextDouble();

    }

    double w,h;

    public double area(){

        return (w*h)/2.0;

    }

}

class Cir extends Sx{

    double r;

    public Cir(){

        r=10*TestCleanCode.r.nextDouble();

    }

    public double area(){

        return Math.PI*r*r;

    }

}


Δευτέρα 14 Αυγούστου 2023

Dangerous Youngers

 ....

what else to say about science,theology etc when main failure is in front !?!!!







............................................................

And what if dangerours youngsters own state !!!



...more basically and i wanted to declare that visible....

You know what is interested!!..fact?

The expansion on games and reality.

So before many year russian came a little down (of cource they killed and the being killed)

Now as usa they declare new states with mama Russia and Papa Italiano(or greek)

Now if they fight with mama Russia (as OY-KRANA did)

and after they will also ask some mercenaries for their -notice the amazing-

..for their expansion...!!!


Meaning yes !!!...they can continiuslly fighting with mama ,,expanding (as not mama)

(continususlly over long term time !...imagine this!)

(and doing like main bastards-from its design- did...when they expanded on America,trators of europe and mama russia)

and after excusing to mama and papa....

And thats life....

North and south goes center and opposite till they(after we) become more bastards...

---

And women?...Approved their brain wikiness !!!!(from all races) 

And we are dead just we dont know it!!!!...as planetary society.


Lies ..lies ,,,,blame others etc ...dogs in a planet with metal transformations!!!

ssss..............


PS

(continususlly over long term time !...imagine this!)

Like some bastards speak as they are greek and for Greece

as they are germans for german (like non blonde Hitler did)

Imagine all that continuslly over planetary time !!!!-for strong users only!

Τετάρτη 31 Μαΐου 2023

FOE_ForgeOfEmpires_Vikings_7_days

....



 
















So, expanding with Horns saves 902-508=394 / 4 factories (with 3 first expansions)
394/4=98.5 ~=100 and with each factory wants 8 hours for 10 goods
100/10=10 *8hours = so SAVING 3 days and 8 hours.

---------------

Strategy 1 ,3 exp with Axles ,3 exp with Meads ,and the rest with Horns...
















(6/6 for onother city note-took 3 exp Axles And 4 exp Horns????)

....

Example of 7,5 days with 5 expansions not need !!!
19 june








Example of 8 days...made mistake three times not gotheriung enough coins and build too soon the MANY factories....so even if i had luck(x4) no coin to continue and spened time ...
27 June 18:00










05 July 12:00 no clans at all(no markets)
7 days,~18 hours (timer doint start at 15 days...next start 13_21)














8,5 days ,bored in many cases to sync...














7 days,2 hours(coold sooner)



7days,10 hours















-------------------------------------------------------

An old example


....

Entering with 5.000 coins, build 2 Factories put x 4 hours(5) = 10   -2.000 coins 








....

bye 2 exp(1+5=6-10 income) remains 4 Axles , 3 Factories x4 hours again
(plus 1 hour till output of 3rd)







....

take 10 more Axles ,delete 2 Factories unlock Shrines and wait
...........    >1 more hour for the 3rd to finish







....

Main lesson for FOE architecture: Push back homes if you hit 5 minutes/....1 hour....







....

This example easy to schedule until unlock Horns for bye all expansions with only Horns .
(Each playthrough is different)











Shedule for 40.000 coins 

-Throw Shrines build 4 Axles Factories.
-4 Axle Factories *8 hour = 40 Axles (-8000 coins)
-4 Axle Factories *8 hour = 40 Axles (-8000 coins)
-Throw 2 Axle Factories unlock and build 2 Meads.
-2 Axle F * 4 hour = 10 Axles + 2 Mead F * 4 hour = 10 Meads (-4000 coins)
-Throw 2 Axle Factories unlock and build 2 Meads.
-4 Mead Factories *8 hour = 40 Meads (-8000 coins)
-4 Mead Factories *4 hour = 20 Meads (-4000 coins)
-Throw all ,unlock Horns build 4 Horns
-4 Horn Factories *4 hour = 20 Horn (-4000 coins)
-Bye 3 expansions ...put Shrines-Houses
-4 Horn Factories *4 hour = 20 Horn (-4000 coins)
-----1 and half day....Continue expanding ALL....

After ~19 hours from Shrines 36.711
+1,5 days our schedule * ~5 house income(93/4 hours) > 40.000








....

Ok,deleted 2 Axle factories, builded some Shrines&Runes for diplomacy,unlocked Meads,deleted Shrines&Runs and build 2 Mead Factories.(Axles will work for 4 hours more to take 10 Axles)





....

Just after 4 hours finish gothering Axles and build 2 more Meads







....

Ok..done ready for Horns.here i was lucky because i took x4 Meads (on 5 order)=20 Meads.
So i didnt just build 4 Horn Factories but also 4 Shrines (bought 2 expansions with Meads.
... but this was not so efficient..maybe..)
From  now on expanding with Horns and depends on the state of coins.
If not have coins (for next order in XX Horn Factories)
........then use new expansions for Shrines.
If have coins then 1 hour before Horn factories finish

a)erase some Shrines ,
b)build 1? horn factory (with the squeres freed up)
c)so when the other factories finish ,,,the new are ready(to be all synchronized)
d)reorder again Horns
e)use Horns just came to bye expansions and build Shrines (and houses)
Same process till all expansions







....

And in the same time doing all above...we must replace some (not all) SHUCKS with HUTS.
Below we see that after i build 1 HUT i sold 5 Shuts and 1 Shrine just for an hour
in order to build 2 more HUTS..(we want some shucks to fill space)







......

Now preparing for build as expand...








....

Now suddenly sold almost all Shrines (i had gother ~25.000 coins) and now 11 factories
but ..just for till finishing coins...After..back to shrines.
Expansion 62 coming and remains 3 (69,76.82)







....

Coming Horns for the last expansion and will start gothering ALL required horns -10 ...
..but i am late...








....

Anyway...failed to finish in 7 days but i have done it...so i will create a new post.
(i think i know what i did wrong here...and also was not my main server...)
below we see that in the end we must have 2 each factories...

15 days -(6 days+14hours-2,5 hours)=15-6.5=

8.5 days .......instead of SEVEN....but gifts are ok...(drasil level plus all fragments)










Κυριακή 30 Απριλίου 2023

Klx230SM-ProMini-Sim800L-NEO-6-Gps

 The fact that europe does not allow us (euro 5 etc..) to have
klx 230 sm
may offer me the time to develop a MINIMAL and effective system in case
that in the future ...i will be able to buy such a perfect (for me) motorbike!!!










Arduino Pro Mini Project.
-We need to be able to Find the gps location of our motorbike in case of bad peopling ...
-We dont need a motion/gyroscope detector(6050) because ....?...
-So we need only gps module , a sim800l and a micro processor...


Estimated cost
15 ,3AA rechargable batteries
8 pro mini
12 sim800l
10 neo6 gps
10(box,wires,solers, breadboard,pins ,on/off button)
10 for 2 relays
10 for voltage regulator @(4.1 vols)

~~~~~
about 75 euros per device....
Advantages
-Low cost (do it yourself) devise
-no yearly expenses just one sim phone card(10 prepaid euros for ...1 year?)
..to send gps loc on thingspeak
 

Disadvantages
-Too much power consumption(need minimized)
-Device must be in a well hidden place but easy to on/off and change batteries
-If device is static when motorbike runs....then do vibration damage electronics in the long run
(especially for someone on wheelies!)?
-be so stupid that you uploading this online(disadvantage for me only!)

Main concept
-Power on
-Find and Hold Gps Location (Home)
-May or may not set up as to inform user by thingspeak update or and call to some phone number
-User can go sleep
-Check every 10(or any other) minutes if we are on same location with some tolerance
-If same location...deep sleep
-If not...then first of all make a call 
-And every 2(or other to minimise battery consumption) minute
Update gps location on thingspeak
---till battery dies !!!!
Maybe better to update every 2 minutes 2 times in 10 seconds just to know also if thief is moving?

Till have my neo6 gps module...just building a sceleton....




---------------------------

learning things....till do it!


Smartphone and Cellular Phone Antenna Design (antenna-theory.com)

https://www.emnify.com/iot-glossary/lte-cat-1







https://content.u-blox.com/sites/default/files/products/documents/u-blox-eCall_WhitePaper_%28MNS-X-11005%29.pdf

SIM808 has intergrated gps...!!!

5G positioning

u blox white paper

This is like what i want but i am focusing just till Thingspeak SIM800L GPS Tracker | Send GPS Data To Server Using Arduino and PHP

https://forum.arduino.cc/t/gps-module-power-management/477859

--------------------------



int xlocHome,ylocHome,zlocHome;
int xlocCurr,ylocCurr,zlocCurr;
int xdif,ydif,zdif;
int xabsdif,yabsdif,zabsdif;
int distTolerance=1;
bool stillHome=true;
void checkStillHome(){
  xdif=xlocCurr-xlocHome;
  if(xdif<0){xabsdif=-xdif;}
  else{xabsdif=xdif;}

  ydif=ylocCurr-ylocHome;
  if(ydif<0){yabsdif=-ydif;}
  else{yabsdif=ydif;}
 
  zdif=zlocCurr-zlocHome;
  if(zdif<0){zabsdif=-zdif;}
  else{zabsdif=zdif;}

  stillHome = (xabsdif<distTolerance)&&(yabsdif<distTolerance)&&(zabsdif<distTolerance);
 
}
long lastMillisTookedForNewLocation;
void settingUpGps(){
  gpsRelayOpen();
  long millisStart=millis();
  prepareGps();
  gpsUpdateCurrLocation();
  long millisEnd=millis();
  lastMillisTookedForNewLocation=millisEnd-millisStart;//may need this for thingspeak field while builing project /or/and to adjust checkingMillis perfectly
  gpsRelayClose();
}

void settingUpSim(){

}
void settingUpTheApplication(){
  settingUpGps();
  settingUpSim();
}
void readCurrLocation(){

}
void settingUpInitialHome(){
  //open sim and gps relay
  readCurrLocation();
  xlocHome=xlocCurr;
  ylocHome=ylocCurr;
  zlocHome=zlocCurr;
  simRelayOpen();
  sendLocationToThingspeak();//primary way to know we are up and running(minimum systems is working fine)
  makeACall();//secondary way may be disabled
  simRelayClose();
}
void setup() {

  settingUpTheApplication();
  //stillHome=true;
  //open gps relay ,check gps is working,get current loc save it to ram
  //close gps relay
  //open sim relay ,check sim is working and send location to thingspeak
  //close sim relay



}

void deepSleep(byte minutes){

}
byte checkingEveryMinutes=10;
void loopJustCheckingLocation(){
  deepSleep(checkingEveryMinutes);
  //open gps relay ,check gps is working,get current loc


}
void loopAlarmOn(){

}


void loop() {
  // put your main code here, to run repeatedly:
  if(locationSame){
    loopJustCheckingLocation();
  }
  else{
    loopAlarmOn();
  }
}



Δευτέρα 6 Φεβρουαρίου 2023

NewtonRaphson Find TimeOfCollision for 2Balls with Deceleration

 Download and run(with java) the .jar

https://drive.google.com/file/d/1gQGtCntPb3NsV14_5K9qgR3ewU--5DzK/view?usp=sharing










NewtonRaphson method for solution x^4









or compile and run....

/*

 * To change this license header, choose License Headers in Project Properties.

 * To change this template file, choose Tools | Templates

 * and open the template in the editor.

 */

package time2ballscollisionwithdeceleration;


import java.awt.BasicStroke;

import java.awt.BorderLayout;

import java.awt.Color;

import java.awt.FlowLayout;

import java.awt.Font;

import java.awt.Graphics;

import java.awt.Graphics2D;

import java.awt.Point;

import java.awt.event.MouseEvent;

import java.awt.event.MouseListener;

import java.awt.event.MouseMotionListener;

import java.awt.event.MouseWheelEvent;

import java.awt.event.MouseWheelListener;

import javax.swing.JButton;

import javax.swing.JCheckBox;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JPanel;

import javax.swing.JSpinner;

import javax.swing.SpinnerNumberModel;



/**

 *

 * @author dimitrak

 */

public class Time2BallsCollisionWithDeceleration extends JFrame implements MouseListener,MouseMotionListener,MouseWheelListener{

    public static void main(String[] args) {

        new Time2BallsCollisionWithDeceleration();

        Balla a=new Balla();

        System.out.println("epibradynsi: "+a.a);

        a.resetAtSpeed(8);

        System.out.println("speed Arxiko "+a.sp);

        System.out.println("distToStop "+a.Ddist(a.timeToStop));

        System.out.println("timeNow : "+a.timeNow);

        System.out.println("Now speed : "+a.spn);

    }

    

    

    Balla a=new Balla();

    Balla b=new Balla();


    Thread thrSim=new Thread(){

        public void run(){

            while(true){

                runSimStep();

            }

        }

    };

    

    

    JLabel jlDt=new JLabel("DT-sim millis");

    JSpinner jspDt=new JSpinner(new SpinnerNumberModel(100,10,1000,10));

    JPanel jpDt=new JPanel(new BorderLayout());

    

    JCheckBox jchPlayReturn=new JCheckBox("return trip",true);

    

    JPanel jpn=new JPanel(new FlowLayout());

    

    

    public Time2BallsCollisionWithDeceleration(){

        super("Find TIME of Collision between 2 balls with (radius,speed,angle , AND DECELARATION from friction)");

    

        a.col=Color.blue;

        b.col=Color.magenta;

        

        

        jpDt.add(BorderLayout.WEST,jlDt);

        jpDt.add(BorderLayout.CENTER,jspDt);

        

        

        jpn.add(jchPlayReturn);

        jpn.add(jbPlay);

        jpn.add(jbTimeZero);

        jpn.add(jpDt);

        

        getContentPane().add(BorderLayout.CENTER,jp);

        getContentPane().add(BorderLayout.NORTH,jpn);

        

        

        setBounds(0,0,777,666);

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        setVisible(true);

        

        jp.addMouseListener(this);

        jp.addMouseMotionListener(this);

        jp.addMouseWheelListener(this);

        

        thrSim.start();

        

        

        jbPlay.addActionListener(e->jbPlay());

        jbTimeZero.addActionListener(e->jbTimeZero());

        

        a.resetAtPos(350,140);

        a.resetAtAngle(Math.toRadians(45));

        a.resetAtSpeed(35);

    

        b.resetAtPos(a.r,400);

        b.resetAtAngle(-Math.toRadians(30));

        b.resetAtSpeed(46);

    

        recomputeCollisionTime();

    }

    

    Graphics2D g=null;

    JPanel jp=new JPanel(){

        public void paintComponent(Graphics gr){

            super.paintComponent(gr);

            g=(Graphics2D)gr;

            paintingBalls();

        }

    };

    Font font=new Font("Dialog",0,16);

    void paintingBalls(){

        

        

        

        

        g.setColor(Color.black);

        g.setFont(font);

        int x=10;

        int y=font.getSize();

        g.drawString("Press IN some ball and dragg mouse to change ball location", x,y);

        y+=font.getSize();

        g.drawString("Mouse Roll a)to change ball Speed ,b)+SHIFT to change ball Angle, c)+SHIFT+CNTRL to change ball DE-CELARATION(friction*g)", x,y);

        y+=font.getSize();

        g.drawString(" "+ex+a.timeCollision, x,y);

        y+=font.getSize();

        g.drawString("Solution/Collision Time : "+a.timeCollision, x,y);

        

        if(a.timeCollision>a.timeToStop && a.timeCollision>b.timeToStop){

            g.setColor(Color.red);

            y+=font.getSize();

            g.drawString("Solution/Collision is on RETURN TRIP...not valid on billiards", x,y);

            

        }

        

        y+=font.getSize();g.setColor(Color.black);

        g.drawString("simTime:"+simTimeSecNow, x,y);

        

        y+=font.getSize();g.setColor(a.col);

        g.drawString("a timeToStop: "+a.timeToStop, x,y);

        y+=font.getSize();g.setColor(b.col);

        g.drawString("b timeToStop: "+b.timeToStop, x,y);

        y+=font.getSize();g.setColor(a.col);

        g.drawString("a dist till collision: "+a.distcol, x,y);

        y+=font.getSize();g.setColor(b.col);

        g.drawString("b dist till collision: "+b.distcol, x,y);

        y+=font.getSize();g.setColor(a.col);

        g.drawString("a acc: "+-a.a, x,y);

        y+=font.getSize();g.setColor(b.col);

        g.drawString("b acc: "+-b.a, x,y);

        

        a.paint(g);

        b.paint(g);

    }

    

    

    

    

    


    @Override

    public void mouseClicked(MouseEvent e) {

    }


    boolean pressedLeft,pressedRight;

    Balla ballNowPressed=a;

    @Override

    public void mousePressed(MouseEvent e) {

        pressedLeft=e.getButton()==MouseEvent.BUTTON1;

        pressedRight=e.getButton()==MouseEvent.BUTTON3;

        ballNowPressed=null;

        double dist1=a.dist(e.getX(),e.getY());

        double dist2=b.dist(e.getX(),e.getY());

        System.out.println(""+dist1+" , "+dist2);

        if(dist1<=a.r && dist1<=dist2){

            ballNowPressed=a;

        }

        if(dist2<=b.r && dist2<=dist1){

            ballNowPressed=b;

        }

        

    

    }


    @Override

    public void mouseReleased(MouseEvent e) {

    }


    @Override

    public void mouseEntered(MouseEvent e) {

    }


    @Override

    public void mouseExited(MouseEvent e) {

    }


    @Override

    public void mouseDragged(MouseEvent e) {

        if(ballNowPressed!=null){

            ballNowPressed.resetAtPos(e.getX(),e.getY());

            recomputeCollisionTime();

        }

    }


    @Override

    public void mouseMoved(MouseEvent e) {

    }


    @Override

    public void mouseWheelMoved(MouseWheelEvent e) {

        

        if(ballNowPressed!=null){

            double mul=1;

            if(e.isAltDown()){

                mul*=10;

            }

            if(!e.isShiftDown()){

                ballNowPressed.resetAtSpeedDif(-mul*e.getWheelRotation());

            }

            else{

                if(!e.isControlDown()){

                    ballNowPressed.resetAtAngleDif(Math.toRadians(-5*e.getWheelRotation()));

                }

                else{

                    ballNowPressed.resetAtAccDif(-mul*0.1*e.getWheelRotation());

                }

            }

            recomputeCollisionTime();

        }

    }

    

    Pol ex=new Pol(4);

    

    public double solNewtonRaphson(double Ax,double Ay,double Asp,double Aacc,double Aang,double Aradius,

                           double Bx,double By,double Bsp,double Bacc,double Bang,double Bradius){

        double dx=Bx-Ax;

        double dy=By-Ay;

        double R=Aradius+Bradius;//dy^2 + dx^2 =R^2

        double d=Aacc/2;

        double c=Bacc/2;

        double h=Asp;

        double e=Bsp;

        double m=Math.cos(Aang);

        double k=Math.cos(Bang);

        double f=Math.sin(Aang);

        double l=Math.sin(Bang);

        double ckdm=c*k-d*m;//coses

        double ekhm=e*k-h*m;//coses

        double cldf=c*l-d*f;//sins

        double elhf=e*l-h*f;//sins

        ex.p[0]=dx*dx + dy*dy - R*R;

        ex.p[1]=2*dx*ekhm + 2*dy*elhf;

        ex.p[2]=ekhm*ekhm + 2*dx*ckdm + elhf*elhf + 2*dy*cldf;

        ex.p[3]=2*ekhm*ckdm + 2*elhf*cldf;

        ex.p[4]=ckdm*ckdm + cldf*cldf;

        

        ex.showAllDerivatives();

        System.out.println("Possible: "+ex.findSomeQuickNewtonRoot());

        return ex.NewtonRaphson(ex.findSomeQuickNewtonRoot(), 100, 0.0000001);

    }

    void recomputeCollisionTime(){

        maxTimeSec=Math.max(a.timeToStop, b.timeToStop);

        if(jchPlayReturn.isSelected()){

            maxTimeSec*=2;

        }

        double t=solNewtonRaphson(

                a.xf,a.yf,a.sp,-a.a,a.an,a.r

                ,b.xf,b.yf,b.sp,-b.a,b.an,b.r

        );

        System.out.println("Collision AT Time: "+t);

        a.resetAtTimeCollision(t);

        b.resetAtTimeCollision(t);


        jp.repaint();

    }

    /**

     * Searching t (collision time)

     * AendX=AstartX+(t*Aspeed)cos(Aangle)

     * AendY=AstartY+(t*Aspeed)sin(Aangle)

     * BendX=BstartX+(t*Bspeed)cos(Bangle)

     * BendY=BstartY+(t*Bspeed)sin(Bangle)

     * 

     * (BendY-AendY)^2 +(BendX-AendX)^2 = (ARadius+BRadius)^2

     *//*

    void recomputeCollisionTime0(){

    

        //System.out.println("recomputing collision time");

        double tLess=-1;

        double aco=a.sp*Math.cos(a.an);

        double asi=a.sp*Math.sin(a.an);

        double bco=b.sp*Math.cos(b.an);

        double bsi=b.sp*Math.sin(b.an);

        double dsi=bsi-asi;

        double dco=bco-aco;

        double dy=b.yf-a.yf;

        double dx=b.xf-a.xf;

        

        double A=dsi*dsi+dco*dco;

        double B=2*((dsi)*(dy)+(dco)*(dx));

        double C=dy*dy+dx*dx-Math.pow(a.r+b.r,2);

        double D=B*B-4*A*C;//System.out.println("D = "+D);

        if(D<0){System.out.println("No solutions");}

        else{

            double t1=(-B-Math.sqrt(D))/(2*A);

            double t2=(-B+Math.sqrt(D))/(2*A);//System.out.println("t1 : "+t1+"   ,   t2: "+t2);

            tLess=t1;

            if(t2<t1){tLess=t2;}

        }

        //a.resetAtTimeCollision(tLess*1000);

        //b.resetAtTimeCollision(tLess*1000);

        

        

        jp.repaint();

    }*/

    

    JButton jbPlay=new JButton("Play");

    JButton jbTimeZero=new JButton("TimeZero");

    

    boolean simPaused=true;

    long pauseMillis=60000;

    long stepMillis=(int)jspDt.getValue();

    double stepSec=((double)stepMillis)/1000d;

    double simTimeMillisNow=0;

    double simTimeSecNow=0;

    double maxTimeSec=10;

    void runSimStep(){

        long sl=pauseMillis;

        if(!simPaused){

            boolean simend=false;

            sl=stepMillis;

            if(jchPlayReturn.isSelected()){

                a.resetAtTimeNow(simTimeSecNow);

                b.resetAtTimeNow(simTimeSecNow);

            }

            else{

                if(a.timeToStop>=simTimeSecNow){

                    a.resetAtTimeNow(simTimeSecNow);

                }

                if(b.timeToStop>=simTimeSecNow){

                    b.resetAtTimeNow(simTimeSecNow);

                }

            }

            

            jp.repaint();

            

            simTimeMillisNow+=stepMillis;

            simTimeSecNow+=stepSec;

            

            if(simTimeSecNow>maxTimeSec){

                simend=true;

                simPause();

                jbTimeZero();

            }

        }

        try{thrSim.sleep(sl);}catch(InterruptedException inter){}

    }

    void jbPlay(){

        if(simPaused){

            simUnPause();

        }

        else{

            simPause();

        }

    }

    void simPause(){

        jbPlay.setText("Play");

        simPaused=true;

        

    }

    

    void simUnPause(){

        jbPlay.setText("Simulating");

        simPaused=false;

        thrSim.interrupt();

    }

    void jbTimeZero(){

        simTimeMillisNow=0;

        simTimeSecNow=0;

    }

    

    

    

    

}


class Balla{

    double coefFriction=0.2;

    double mass=0.2;

    double g=10;

    double a=coefFriction*g;

    

    

    Color col=Color.BLUE;

    double r=50;

    double d=2*r;

    double xf=2*r+Math.random()*300,yf=2*r+Math.random()*300;

    double an=Math.toRadians(Math.random()*360);

    double sp=10+Math.random()*10;

    double xl,yl;


    double timeToStop=sp/a;

    double xe,ye;

    

    double timeNow=timeToStop/2;

    double spn=sp-a*timeNow;

    double xn,yn;

    

    double timeCollision=-1;

    double spcol=sp-a*timeCollision;

    double distcol=(Ddist(timeCollision));

    double xc,yc;

    

    public Balla(){

        resetAtPos();

    }

    void resetAtPos(){

        resetAtPos(xf, yf);

    }

    void resetAtPosold(double x,double y){

        xf=x;

        yf=y;

        xl=xf+r*Math.cos(an);

        yl=yf+r*Math.sin(an);

        //1000 millis sp

        //timeEnd  x?

        double distMaxTime=(sp*timeToStop)/1000;

        xe=xf+distMaxTime*Math.cos(an);

        ye=yf+distMaxTime*Math.sin(an);

        

        double distNowTime=(sp*timeNow)/1000;

        xn=xf+distNowTime*Math.cos(an);

        yn=yf+distNowTime*Math.sin(an);

        

        if(timeCollision>0){

            xc=xf+distcol*Math.cos(an);

            yc=yf+distcol*Math.sin(an);

            

        }

    }

    

    public double Ddist(double t){

        double out=sp*t-((a*t*t)/2);

        return out;

    }

    void resetAtPos(double x,double y){

        xf=x;

        yf=y;

        xl=xf+r*Math.cos(an);

        yl=yf+r*Math.sin(an);

        //1000 millis sp

        //timeEnd  x?

        double distMaxTime=(Ddist(timeToStop));

        //System.out.println("distMaxTime: " +distMaxTime+" for timeToStop="+timeToStop);

        xe=xf+distMaxTime*Math.cos(an);

        ye=yf+distMaxTime*Math.sin(an);

        

        double distNowTime=(Ddist(timeNow));

        xn=xf+distNowTime*Math.cos(an);

        yn=yf+distNowTime*Math.sin(an);

        

        if(timeCollision>0){

            double distAtCollision=(Ddist(timeCollision));

            xc=xf+distAtCollision*Math.cos(an);

            yc=yf+distAtCollision*Math.sin(an);

            

        }

    }

    void resetAtAngle(double newAngle){

        an=newAngle;

        resetAtPos();

    }

    void resetAtAngleDif(double difAngle){

        resetAtAngle(difAngle+an);

    }

    void resetAtSpeed(double newSpeed){

        sp=newSpeed;

        timeToStop=sp/a;

        spn=sp-a*timeNow;

        System.out.println(sp+" m/ss -> TimeToStop = "+timeToStop);

        resetAtPos();

    }

    void resetAtSpeedDif(double difSpeed){

        resetAtSpeed(difSpeed+sp);

    }

    void resetAtTimeNow(double newNowTime){

        timeNow=newNowTime;

        spn=sp-a*timeNow;

        resetAtPos();

    }

    void resetAtTimeCollision(double newCollisionTime){

        timeCollision=newCollisionTime;

        spcol=sp-a*timeCollision;

        distcol=(sp*timeCollision)/1000;

        resetAtPos();

    }

    void resetAtAcc(double accNew){

        accNew=Math.abs(accNew);

        a=accNew;

        timeToStop=sp/a;

        spn=sp-a*timeNow;

        resetAtPos();

    }

    void resetAtAccDif(double accDif){

        resetAtAcc(a+accDif);

        System.out.println(""+a);

    }

    

    public double dist(double x,double y){

        return Point.distance(xf, yf, x, y);

    }


    static BasicStroke strokeNormal=new BasicStroke(1);

    static BasicStroke strokeMoving=new BasicStroke(1,0,0,10,new float[]{10,10},0);

    public void paint(Graphics2D g){

        g.setStroke(strokeNormal);

        g.setColor(col);

        g.drawOval((int)(xf-r),(int)(yf-r), (int)(d),(int)( d));

        g.drawLine((int)(xf),(int)(yf),(int)(xl),(int)(yl));

        g.drawOval((int)(xe-r),(int)(ye-r), (int)(d),(int)( d));

        g.drawLine((int)(xf),(int)(yf),(int)(xe),(int)(ye));

        

        g.drawString("V0="+(nice(sp))+" m/s", (int)(xf),(int)(yf));

        

        

        g.setStroke(strokeMoving);

        g.drawOval((int)(xn-r),(int)(yn-r), (int)(d),(int)( d));

        g.drawString("V="+(nice(spn))+" m/s", (int)(xn),(int)(yn));

        

        if(timeCollision>0){

            g.setColor(Color.RED);

            g.setStroke(strokeNormal);

            int ucx=(int)(xc-r);

            int ucy=(int)(yc-r);

            g.drawOval(ucx,ucy, (int)(d),(int)( d));

            //g.drawLine(ucx,ucy,(int)(ucx+d),(int)(ucy+d));

        }

    }

    

    static double nice(double d){

        d*=1000;

        d=(long)d;

        d/=1000;

        return d;

    }

}

class JNewtonRaphson {

    public static void main(String[] args) {


    }

    static void test(){

        Pol p=new Pol(3,-7,1,2,-19);

        System.out.println(""+p);

        System.out.println(""+p.strf(-1));

        System.out.println(""+p.strf(0));

        System.out.println(""+p.strf(1));

        System.out.println(""+p.hasSolutionAt(-100, 100, 1));

        System.out.println(""+p.findSomeQuickNewtonRoot());

        p.showAllDerivatives();

        System.out.println("--------------");

        p.NewtonRaphson(0, 100, 0.0000001);

        

        

    }

    

    

}


class Pol{

    double[]p;

    

    public Pol(int maxPower){

        p=new double[maxPower+1];

    }

    public Pol(double []ps){

        this(ps,false);

    }

    public Pol(double []ps,boolean assign){

        if(assign){

            p=ps;

        }

        else{

            p=new double[ps.length];

            System.arraycopy(ps, 0, p, 0, ps.length);

        }

    }

    

    public Pol(double p2,double p1,double c){

        this(2);

        p[0]=c;

        p[1]=p1;

        p[2]=p2;

    }

    public Pol(double p3,double p2,double p1,double c){

        this(3);

        p[0]=c;

        p[1]=p1;

        p[2]=p2;

        p[3]=p3;

    }

    public Pol(double p4,double p3,double p2,double p1,double c){

        this(4);

        p[0]=c;

        p[1]=p1;

        p[2]=p2;

        p[3]=p3;

        p[4]=p4;

    }

    

    public double NewtonRaphson(double xPossible,int maxsteps,double epsilon){

        

        Pol ft=getfDerivative();

        double x=xPossible;

        double h = fHorner(x) / ft.fHorner(x);

        int i=0;

        while (i<maxsteps && Math.abs(h) >= epsilon){

            x -=h;

            h = fHorner(x) / ft.fHorner(x);

            //System.out.println(i+" : "+x);

            ++i;

        }

        //System.out.println("sol: "+x);

        System.out.println(""+strf(x));

        return x;

    }


    public void showAllDerivatives(){

        Pol a=this;

        int ton=0;

        while(a.p.length>1){

            System.out.println("f["+(ton)+"](x)="+a);

            a=a.getfDerivative();

            ++ton;

        }

        System.out.println("f["+(ton)+"](x)="+a);

    }

    public Pol getfDerivative(){

        int l=p.length;

        if(p.length<2){

            return new Pol(0);//y=0;

        }

        l-=1;

        double ps[]=new double[l];

        int pos=l-1;

        while(l>0){

            ps[pos]=p[l]*l;

            --pos;

            --l;

        }

        return new Pol(ps,true);

    }

    public double findSomeQuickNewtonRoot(){

        double out=hasSolutionAt(-10, 10,0.1);//200 max

        if(Double.isNaN(out)){

            out=hasSolutionAt(-100, 100,1);//200 max

            if(Double.isNaN(out)){

                out=hasSolutionAt(-1000, 1000,10);//200 max

                if(Double.isNaN(out)){

                    out=hasSolutionAt(-10000, 10000,100);//200 max

                }

            }

        }

        return out;

    }

    public double hasSolutionAt(double x1,double x2,double xstep){

        if(x2<x1){

            double temp=x2;

            x2=x1;

            x1=temp;

        }

        else if(x1<x2){

            

        }

        else{

            

        }

        if(xstep<0){

            xstep=-xstep;

        }

        else if(xstep>0){}

        else{

            xstep=x2-x1;

            xstep/=100;

        }

        

        double x=x1;

        double y=fHorner(x);

        boolean startNeg=false;

        if(y<0){

            startNeg=true;

        }

        else if(y>0){

            

        }

        else{

            return x;

        }

        x+=xstep;

        x2+=xstep;

        while(x<x2){

            y=fHorner(x);

            if(y<0){

                if(!startNeg){

                    return x-xstep/2;

                }

            }

            else if(y>0){

                if(startNeg){

                    return x-xstep/2;

                }

            }

            else{

                return x;

            }

            x+=xstep;

        }

        

        

        return Double.NaN;

    }

    

    public double fHorner(double x){

        int i=p.length-1;

        double out=p[i];

        --i;

        while(i>=0){

            out*=x;

            out+=p[i];

            --i;

        }

        return out;

    }

    

    public double fOld(double x){

        int i=0;

        double v=p[i];

        double out=v;

        double xs=1;

        ++i;

        while(i<p.length){

            xs*=x;

            out+=xs*p[i];

            ++i;

        }

        return out;

    }

    public double f(double x){

        return fHorner(x);

    }

    public String strf(double x){

        return "f("+x+") = "+f(x);

    }


    

    public String toString(){

        String out="";

        int i=p.length-1;

        double v;

        while(i>0){

            v=p[i];

            if(v>0){

                out+="+"+v+"(x^"+i+") ";

            }

            else if(v<0){

                out+=""+v+"(x^"+i+") ";

            }

            --i;

        }

        v=p[i];

        if(v>0){

            out+="+"+v;

        }

        else if(v<0){

            out+=""+v;

        }

        else{

            if(p.length==1){

                out+="+0";

            }

        }

        

        return out;

    }

}


Κυριακή 5 Φεβρουαρίου 2023

Collision Time For Two Balls

download and run this

https://drive.google.com/file/d/1_IPdpTKzLNTJYxBxxbtJyAkH3dnFwSZD/view?usp=sharing


//or....stand alone / ready to compile and run simple code










/*

 * To change this license header, choose License Headers in Project Properties.

 * To change this template file, choose Tools | Templates

 * and open the template in the editor.

 */

package j2ballscollisionfounder;


import java.awt.BasicStroke;

import java.awt.BorderLayout;

import java.awt.Color;

import java.awt.FlowLayout;

import java.awt.Font;

import java.awt.Graphics;

import java.awt.Graphics2D;

import java.awt.Point;

import java.awt.event.MouseEvent;

import java.awt.event.MouseListener;

import java.awt.event.MouseMotionListener;

import java.awt.event.MouseWheelEvent;

import java.awt.event.MouseWheelListener;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JPanel;

import javax.swing.JSpinner;

import javax.swing.SpinnerNumberModel;


/**

 *

 * @author dimitrak

 */

public class J2BallsCollisionFounder extends JFrame implements MouseListener,MouseMotionListener,MouseWheelListener{

    public static void main(String[] args) {

        new J2BallsCollisionFounder();

    }

    

    

    Balla a=new Balla();

    Balla b=new Balla();


    Thread thrSim=new Thread(){

        public void run(){

            while(true){

                runSimStep();

            }

        }

    };

    

    

    JLabel jlDt=new JLabel("DT-sim millis");

    JSpinner jspDt=new JSpinner(new SpinnerNumberModel(100,10,1000,10));

    JPanel jpDt=new JPanel(new BorderLayout());

    

    JPanel jpn=new JPanel(new FlowLayout());

    

    

    public J2BallsCollisionFounder(){

        super("Found TIME of Collision between 2 balls with (radius,speed,angle)");

    

        b.col=Color.black;

        

        

        jpDt.add(BorderLayout.WEST,jlDt);

        jpDt.add(BorderLayout.CENTER,jspDt);

        

        

        jpn.add(jbPlay);

        jpn.add(jbTimeZero);

        jpn.add(jpDt);

        

        getContentPane().add(BorderLayout.CENTER,jp);

        getContentPane().add(BorderLayout.NORTH,jpn);

        

        

        setBounds(0,0,777,666);

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        setVisible(true);

        

        jp.addMouseListener(this);

        jp.addMouseMotionListener(this);

        jp.addMouseWheelListener(this);

        

        thrSim.start();

        

        

        jbPlay.addActionListener(e->jbPlay());

        jbTimeZero.addActionListener(e->jbTimeZero());

        

        a.resetAtPos(300,100);

        a.resetAtAngle(Math.PI/2);

        a.resetAtSpeed(60);

    

        b.resetAtPos(100,300);

        b.resetAtAngle(-Math.PI/8);

        b.resetAtSpeed(60);

    

        recomputeCollisionTime();

    }

    

    Graphics2D g=null;

    JPanel jp=new JPanel(){

        public void paintComponent(Graphics gr){

            super.paintComponent(gr);

            g=(Graphics2D)gr;

            paintingBalls();

        }

    };

    Font font=new Font("Dialog",0,16);

    void paintingBalls(){

        

        

        

        

        g.setColor(Color.black);

        g.setFont(font);

        int x=10;

        int y=font.getSize();

        g.drawString("Press IN some ball and dragg mouse to change ball location", x,y);

        y+=font.getSize();

        g.drawString("Mouse Roll to change ball Speed", x,y);

        y+=font.getSize();

        g.drawString("Mouse Roll +SHIFT to change ball Angle", x,y);

        

        a.paint(g);

        b.paint(g);

    }

    

    

    

    

    


    @Override

    public void mouseClicked(MouseEvent e) {

    }


    boolean pressedLeft,pressedRight;

    Balla ballNowPressed=a;

    @Override

    public void mousePressed(MouseEvent e) {

        pressedLeft=e.getButton()==MouseEvent.BUTTON1;

        pressedRight=e.getButton()==MouseEvent.BUTTON3;

        ballNowPressed=null;

        double dist1=a.dist(e.getX(),e.getY());

        double dist2=b.dist(e.getX(),e.getY());

        System.out.println(""+dist1+" , "+dist2);

        if(dist1<=a.r && dist1<=dist2){

            ballNowPressed=a;

        }

        if(dist2<=b.r && dist2<=dist1){

            ballNowPressed=b;

        }

        

    

    }


    @Override

    public void mouseReleased(MouseEvent e) {

    }


    @Override

    public void mouseEntered(MouseEvent e) {

    }


    @Override

    public void mouseExited(MouseEvent e) {

    }


    @Override

    public void mouseDragged(MouseEvent e) {

        if(ballNowPressed!=null){

            ballNowPressed.resetAtPos(e.getX(),e.getY());

            recomputeCollisionTime();

        }

    }


    @Override

    public void mouseMoved(MouseEvent e) {

    }


    @Override

    public void mouseWheelMoved(MouseWheelEvent e) {

        

        if(ballNowPressed!=null){

            if(!e.isShiftDown()){

                ballNowPressed.resetAtSpeedDif(-5*e.getWheelRotation());

            }

            else{

                ballNowPressed.resetAtAngleDif(Math.toRadians(-5*e.getWheelRotation()));

            }

            recomputeCollisionTime();

        }

    }

    

    /**

     * Searching t (collision time)

     * AendX=AstartX+(t*Aspeed)cos(Aangle)

     * AendY=AstartY+(t*Aspeed)sin(Aangle)

     * BendX=BstartX+(t*Bspeed)cos(Bangle)

     * BendY=BstartY+(t*Bspeed)sin(Bangle)

     * 

     * (BendY-AendY)^2 +(BendX-AendX)^2 = (ARadius+BRadius)^2

     */

    void recomputeCollisionTime(){

        //System.out.println("recomputing collision time");

        double tLess=-1;

        double aco=a.sp*Math.cos(a.an);

        double asi=a.sp*Math.sin(a.an);

        double bco=b.sp*Math.cos(b.an);

        double bsi=b.sp*Math.sin(b.an);

        double dsi=bsi-asi;

        double dco=bco-aco;

        double dy=b.yf-a.yf;

        double dx=b.xf-a.xf;

        

        double A=dsi*dsi+dco*dco;

        double B=2*((dsi)*(dy)+(dco)*(dx));

        double C=dy*dy+dx*dx-Math.pow(a.r+b.r,2);

        double D=B*B-4*A*C;//System.out.println("D = "+D);

        if(D<0){System.out.println("No solutions");}

        else{

            double t1=(-B-Math.sqrt(D))/(2*A);

            double t2=(-B+Math.sqrt(D))/(2*A);//System.out.println("t1 : "+t1+"   ,   t2: "+t2);

            tLess=t1;

            if(t2<t1){tLess=t2;}

        }

        a.resetAtTimeCollision(tLess*1000);

        b.resetAtTimeCollision(tLess*1000);

        

        

        jp.repaint();

    }

    

    JButton jbPlay=new JButton("Play");

    JButton jbTimeZero=new JButton("TimeZero");

    

    boolean simPaused=true;

    long stepMillis=100;

    long pauseMillis=60000;

    double simTime=0;

    double simDtime(){return (int)jspDt.getValue();}

    double simMaxtime=5000;

    void runSimStep(){

        long sl=pauseMillis;

        if(!simPaused){

            boolean simend=false;

            sl=stepMillis;

            simTime+=simDtime();

            if(simTime>simMaxtime){

                simTime=simMaxtime;

                simend=true;

            }

            a.resetAtTimeNow(simTime);

            b.resetAtTimeNow(simTime);

            jp.repaint();

            

            if(simend){

                simPause();

                simTime=0;

            }

        }

        try{thrSim.sleep(sl);}catch(InterruptedException inter){}

    }

    void jbPlay(){

        if(simPaused){

            simUnPause();

        }

        else{

            simPause();

        }

    }

    void simPause(){

        jbPlay.setText("Play");

        simPaused=true;

        

    }

    

    void simUnPause(){

        jbPlay.setText("Simulating");

        simPaused=false;

        thrSim.interrupt();

    }

    void jbTimeZero(){

        simTime=0;

    }

    

    

    

    

}


class Balla{

    Color col=Color.BLUE;

    double r=50;

    double d=2*r;

    double xf=2*r+Math.random()*300,yf=2*r+Math.random()*300;

    double an=Math.toRadians(Math.random()*360);

    double sp=10+Math.random()*100;

    double xl,yl;

    

    double timeEnd=5000;

    double xe,ye;

    

    double timeNow=timeEnd/2;

    double xn,yn;

    

    double timeCollision=-1;

    double xc,yc;

    

    public Balla(){

        resetAtPos();

    }

    void resetAtPos(){

        resetAtPos(xf, yf);

    }

    void resetAtPos(double x,double y){

        xf=x;

        yf=y;

        xl=xf+r*Math.cos(an);

        yl=yf+r*Math.sin(an);

        //1000 millis sp

        //timeEnd  x?

        double distMaxTime=(sp*timeEnd)/1000;

        xe=xf+distMaxTime*Math.cos(an);

        ye=yf+distMaxTime*Math.sin(an);

        

        double distNowTime=(sp*timeNow)/1000;

        xn=xf+distNowTime*Math.cos(an);

        yn=yf+distNowTime*Math.sin(an);

        

        if(timeCollision>0){

            double distAtCollision=(sp*timeCollision)/1000;

            xc=xf+distAtCollision*Math.cos(an);

            yc=yf+distAtCollision*Math.sin(an);

            

        }

    }

    void resetAtAngle(double newAngle){

        an=newAngle;

        resetAtPos();

    }

    void resetAtAngleDif(double difAngle){

        resetAtAngle(difAngle+an);

    }

    void resetAtSpeed(double newSpeed){

        sp=newSpeed;

        resetAtPos();

    }

    void resetAtSpeedDif(double difSpeed){

        resetAtSpeed(difSpeed+sp);

    }

    void resetAtTimeNow(double newNowTime){

        timeNow=newNowTime;

        resetAtPos();

    }

    void resetAtTimeCollision(double newCollisionTime){

        timeCollision=newCollisionTime;

        resetAtPos();

    }

    

    public double dist(double x,double y){

        return Point.distance(xf, yf, x, y);

    }


    static BasicStroke strokeNormal=new BasicStroke(1);

    static BasicStroke strokeMoving=new BasicStroke(1,0,0,10,new float[]{10,10},0);

    public void paint(Graphics2D g){

        g.setStroke(strokeNormal);

        g.setColor(col);

        g.drawOval((int)(xf-r),(int)(yf-r), (int)(d),(int)( d));

        g.drawLine((int)(xf),(int)(yf),(int)(xl),(int)(yl));

        g.drawOval((int)(xe-r),(int)(ye-r), (int)(d),(int)( d));

        

        double spn=sp*1000;

        spn=(long)spn;

        spn/=1000;

        g.drawString("V="+(spn)+" px/s", (int)(xf),(int)(yf));

        

        

        g.setStroke(strokeMoving);

        g.drawOval((int)(xn-r),(int)(yn-r), (int)(d),(int)( d));

        

        if(timeCollision>0){

            g.setColor(Color.RED);

            g.setStroke(strokeNormal);

            int ucx=(int)(xc-r);

            int ucy=(int)(yc-r);

            g.drawOval(ucx,ucy, (int)(d),(int)( d));

            //g.drawLine(ucx,ucy,(int)(ucx+d),(int)(ucy+d));

        }

    }

}