Bir algooritma sorusu

Başlatan Mucit23, 30 Haziran 2012, 13:58:05

Mucit23

Arkadaşlar bir sorum var. Biraz uğraştım ama işin içinden çıkamadım

Bir sayımız var. Bu sayının değeri bir değişken içerisinde tutuluyor ve Değeri 0 ile 360 arasında sürekli olarak değişiyor. Be bu değişken sayının 5 eksiğini ve 5 fazlasını ayrı değişkenler içerisinde tutmam gerekiyor.

örneğin asıl sayımızın değeri 273 ise 5 fazlası olan 278 değeri başka bir değişkende, 5 eksiği olan 268 değeri başka bir değişkende saklanması gerekiyor. Eğer ana saymızın değeri değişirse bu sayılarında değeri güncellenecek. Şimdi eğer sayı 4 den büyük veya 356 dan küçğk ise problem olmuyor zaten. Ama diyelimki sayımız 357 ise bu sayıya 5 eklediğimiz zaman yeni sayının değeri 362 olur. Ama yardımcı sayılarda 360 değerini geçmemeli. 360dan büyük ise 360dan sonraki sayı değeri alınmalı. Yani ana sayımız 357 sayısınına 5 eklersek  sayı değeri 362 olur. Biz ise 360dan sonraki 2 değerini sadece almalıyız. Sonuç olarak 357 sayısının 5 fazlası 2 olarak yardımcı değişkene yerleştrilmeli.

Aynı şekilde 5 eksiğide buna benzer bir sistemde çalışacak.
Diyelimki ana sayımız 2 ise bu sayının 5 eksiği 357 olmalı. İşte burada ipin ucunu kaçırdım. doğru düzgün bir alogritma kuramadım. Bunu nasıl yapabilirim.

controller

int deg, bes_eksik;

deg = 2;

if( (deg - 5) < 0 )
{
bes_eksik = 360 - (5 - deg);
}
else bes_eksik = deg - 5;
Hesabım OG tarafından haksız bir şekilde pasif yapılmıştır.

Mucit23

Protonda yazıyordum. Ben bir algooritma kurdum ama protonda 0dan başka bir sayıyı çıkartınca herseferinde anlamsız bir sayı geliyor. Sayı tipi word..

controller

işaretli tamsayı varsa onu kullan. işaretsiz tamsayı varsa if satırını şöyle değiştir.

if( (deg - 5) > 360 )
Hesabım OG tarafından haksız bir şekilde pasif yapılmıştır.

Mucit23

Tamam senin verdiğin kodlardan yola çıkarak aklıma bir yöntem daha geldi. Akşam onuda deniyeceğim.

Başka  önerisi olan varmı?

matador

int ana_deger,eksik,fazla;

eksik=ana_deger-5;
if ana_deger<=4 Then
   eksik=ana_deger
endif

fazla=ana_deger+5;
if fazla>=361 Then
   fazla=fazla-360
endif

Hocam aklıma başka bir şey gelmedi.

MrDarK

#define sabit_max 360

unsigned char buffer;

if(ana_sayi<=4)
{
  buffer=5-ana_sayi;
  sonuc1=sabit_max-buffer;
}
if(ana_sayi>=356)
{
  buffer=sabit_max-ana_sayi;
  sonuc2=5-buffer;
}

Hocam Hi-tech C veya Ansii C tabanlı yazdım bunu kendi yazdığın programlama diline göre uyarla derim :)
Picproje Eğitim Gönüllüleri ~ MrDarK

OG

#7
Dim anasayi As Word
Dim yard_1 As Word
Dim yard_2 As Word

Basla:
    
    anasayi_ne
    GoSub hesapla
    
    sunubunu_yap
GoTo Basla

hesapla:
    If anasayi > 4 And anasayi < 356 Then
        yard_1 = anasayi - 5
        yard_2 = anasayi + 5
        Return
    EndIf
    
    If anasayi > 355 Then
        yard_1 = anasayi - 5
        yard_2 = anasayi - 355
        Return
    EndIf
    
    If anasayi < 5 Then
        yard_1 = 360 - ( 5 - anasayi )
        yard_2 = anasayi + 5
        Return
    EndIf
Return
   
FORUMU İLGİLENDİREN KONULARA ÖM İLE CEVAP VERİLMEZ.

Mucit23

OG hocama ve diğer arkadaşlar teşekkürler. hallettim ben :)

F.T

Mucit23 nasıl bir yöntemle hallettin?
Hakk şerleri hayr eyler Zannetme ki gayr eyler Ârif anı seyreyler Mevlâ görelim neyler Neylerse güzel eyler.

Mucit23

#10
Arkadaşlar tekrardan merhaba,

Konuyu açma amacım analog ibre benzeri birşeyler yapmaktı. Yaptım ama sonuçtan pek tatmin olmadım.
Yaptığım uygulamanın videosu burada

http://youtu.be/URmHkTxtzMg

Kodları ise budur.

Device 18F452

Xtal 20

Config_Start
   OSC = HS ; HS
   PWRT = On ; Enabled
   WDT = OFF ; Disabled
   Debug = OFF ; Disabled
Config_End
  
TRISA=%00000000
TRISB=%00000000
TRISC=%00000000
TRISD=%00000000
TRISE=%00000000

PORTA=0:PORTB=0
PORTC=0:PORTD=0
    PORTE=0
PORTB.5=1                          'GLCD RESET=1
LCD_DTPort = PORTD                 'GLCD DATA PORTLARI PORTD'YE BAĞLI
LCD_RSPin = PORTB.0                'GLCD RS PİNİ PORTB.0 BAĞLI
LCD_ENPin = PORTB.2                'GLCD ENABLE PİNİ PORTB.2 BAĞLI
LCD_RWPin = PORTB.1                'GLCD RW PİNİ PORTB.1 BAĞLI
LCD_CS1Pin = PORTB.4               'GLCD CS1 PİNİ PORTB.4 BAĞLI
LCD_CS2Pin = PORTB.3               'GLCD CS2 PİNİ PORTB.3 BAĞLI
LCD_Type =  Samsung                'GLCD TİPİ GRAFİK KS0108 128*64B WİNSTAR
Declare Internal_Font = On
Declare Font_Addr = 0
Declare GLCD_STROBE_DELAY = 4
;GLCD_EXTERNAL_PRINT = PPRINT
DelayMS 100

Dim Pi     As Float  ; Pi Değeri 3,1415
Dim AX     As Float  ; Açı Değerinin Radyana çevrilmiş Hali
Dim DX     As Float  ;
Dim ZX     As Float  ;
Dim AXpos  As Word   ; Dış çemberin X Eksenindeki kordinatı
Dim AYpos  As Word   ; Dış çemberin Y Eksenindeki kordinatı
Dim DXpos  As Word   ; 1. iç çemberin X Eksenindeki kordinatı
Dim DYpos  As Word   ; 1. iç çemberin Y Eksenindeki kordinatı
Dim ZXpos  As Word   ; 2. iç çemberin X Eksenindeki kordinatı
Dim ZYpos  As Word   ; 2. iç çemberin Y Eksenindeki kordinatı 
Dim AXpos_ As Word   ; Dış çemberin X Eksenindeki Eski kordinat
Dim AYpos_ As Word   ; Dış çemberin Y Eksenindeki Eski kordinat
Dim DXpos_ As Word   ; 1. iç çemberin X Eksenindeki Eski kordinat
Dim DYpos_ As Word   ; 1. iç çemberin Y Eksenindeki Eski kordinat
Dim ZXpos_ As Word   ; 2. iç çemberin X Eksenindeki Eski kordinat
Dim ZYpos_ As Word   ; 2. iç çemberin Y Eksenindeki Eski kordinat
Dim Angle  As Word   ; Açı Değeri
Dim Xngle  As Word   ; Açı Değerinin 5 Eksiği
Dim Zngle  As Word   ; Açı Değerinin 5 Fazlası
Dim DSize  As Byte   ; Dış eksen çapı
Dim MSize  As Byte   ; Merkez eksen çapı
Dim MX     As Byte   ; Orjin Noktasının X kordinatı
Dim MY     As Byte   ; Orjin Noktasının Y kordinatı

Pi=3.1415            ; Pi Değeri Belirleniyor
Cls                  ; Ekran Temizleniyor

MX=64:MY=32          ; Burada Ekrana çizilecek çizginin Başlangıç noktası belirlenir. Ekranın Tam ortasında olacağı için 
                     ; Kordinatlarımızı 32,64 olarak belirliyoruz
DSize = 30           ; Çizgimizin uzunluğu
MSize = 10           ; Merkez Eksen çapı 

BASLA:

For Angle=0 To 359

  If Angle>354 Then 
    Zngle=(ANGLE+20)-360
  Else
    Zngle=ANGLE+20
  EndIf 
  If Angle<5 Then
     Xngle=360-(20-Angle)
  Else
     Xngle=ANGLE-20
  EndIf

  AXpos = DSize * Cos (Pi * Angle)/180
  AYpos = DSize * Sin (Pi * Angle)/180 
  DXpos = MSize * Cos (Pi * Angle)/180 
  DYpos = MSize * Sin (Pi * Angle)/180
  ZXpos = MSize * Cos (Pi * Angle)/180
  ZYpos = MSize * Sin (Pi * Angle)/180

  Line 0,(MX+DXPOS_),(MY+DYPOS_),(MX+AXPOS_),(MY+AYPOS_)
  Line 0,(MX+ZXPOS_),(MY+ZYPOS_),(MX+AXPOS_),(MY+AYPOS_)  
  Line 1,(MX+DXPOS),(MY+DYPOS),(MX+AXPOS),(MY+AYPOS)
  Line 1,(MX+ZXPOS),(MY+ZYPOS),(MX+AXPOS),(MY+AYPOS)  

  AYpos_=AYpos:AXpos_=AXpos          ; Bir önceki kordinatlar belirleniyor  
  DYpos_=DYpos:DXpos_=DXpos
  ZYpos_=ZYpos:ZXpos_=ZXpos
  Print At 0,0,"ACI=",Dec3 Angle  
DelayMS 100  
Next

GoTo BASLA

Include "FONT.inc"

End


Acaba pixel yoğunluğunun az olmasındanmı kaynaklanıyor bilmiyorum ama göze okadarda güzel görünmedi. Sizin fikirlerinizi almak isterim. Bu işi yapmanın daha iyi yolu varmıdır.

Mesela oradaki ibreyi kendim çizeceğime resim olarak basıp resmi döndürebilirmiyiz. Resim döndürme algooritmaları vardı

Mucit23

Güncel
Yorum ve önerilerinizi bekliyorum

esensoy

bence açı değeri bildirmek adına güzel olmuş,
yalnız sınırlar olmadan kel gibi görünüyor,
içe küçük bir daire, dışa da doğruların birleştiği noktanın süpürdüğü daireyi çizersen daha anlamlı ve güzel görünecektir diye düşünüyorum,

resim döndürmeye gelince birincisi döndüreceğin şekil sade ise belki olur, ama karışık ise bu çözünürlükte bu ekranla iyice anlaşılmaz olacaktır,
bu noktada kullanıcı gibi bakmak, empati yapmak gerekiyor,
En tehlikeli an "zafer" anıdır.

Mucit23

Dediğiniz gibi ortada bir yuvarlak olsa güzel olacak. Onu yaparım kolayda yanlız iç çemberdeki iki başlangıç noktası herzaman eş zamanlı olarak hareket etmiyor. Sorun işte burada. Tabi bu tamamiyle matematiksel işlemlerle alakalı.  Normalde kabul edilebilir bir hata payıdır ama işte burada olmayınca görüntü güzel olmuyor. Buna çözüm arıyorum öncelikle

mehmet

Oluşabilecek değerleri excel gibi bir tablo içinde
önceden hesaplansa, bu değerleri bir dizi içinde
saklansa ve her seferinde yeniden hesaplama
yapılmasına gerek kalmaz. Mcu'yu da fazla
yormadan gereken degerler verilmiş olur
düşüncesindeyim.

Saygılar...
Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
---------------------------------------------
http://www.mehmetbilgi.net.tr